模拟
五步做完 :
①遍历链表,得到链表长度
②找到中间结点
③反转链表后半段的结点指向
④重排链表
⑤尾结点的指向置空
初始链表
L
0
→
L
1
→
…
→
L
n
−
1
→
L
n
L0 → L1 → … → Ln - 1 → Ln
L0→L1→…→Ln−1→Ln
重排链表
L
0
→
L
n
→
L
1
→
L
n
−
1
→
L
2
→
L
n
−
2
→
…
L0 → Ln → L1 → Ln - 1 → L2 → Ln - 2 → …
L0→Ln→L1→Ln−1→L2→Ln−2→…
初始链表到重排链表的关系:从头结点往右,每两个结点之间插入未使用的尾结点。
看反转后的链表,是不是很容易得到重排链表啊?是的。那个图的连线过于凌乱,想了解透彻的读者可以自己画图。算法实现请看代码。
class Solution {
public:
void reorderList(ListNode* head) {
auto a = head;
int n = 0;
for(;a;a = a->next) n++;
auto mid = head;
for(int i = 0;i<(n+1)/2-1;i++) mid = mid ->next;
auto b = mid ->next;
a = mid;
while(b){
auto c = b->next;
b->next = a, a = b , b = c;
}
auto p = head , q = a;
for(int i = 0;i<n/2;i++){
auto o = q->next;
q ->next = p->next;
p->next = q;
p = q->next;
q = o;
}
if(n&1) mid ->next = NULL;
else mid->next->next = NULL;
}
};
- 时间复杂度 : O ( n ) O(n) O(n) , n n n 是链表长度, 遍历链表常数次,忽略常数时间复杂度 O ( n ) O(n) O(n) 。
- 空间复杂度 : O ( 1 ) O(1) O(1) , 只使用常数级空间 。
AC
致语
- 理解思路很重要
- 读者有问题请留言,清墨看到就会回复的。