206. Reverse Linked List [easy]
Reverse a singly linked list.
Example:
Input: 1->2->3->4->5->NULL
Output: 5->4->3->2->1->NULL
Follow up:
A linked list can be reversed either iteratively or recursively. Could you implement both?
- 思路1:用多个指针就好。ptr指向当前节点。pre上一个,next下一个。ptr->next指向pre。然后三个指针往后移一步就好。
- 复杂度:time O(N), space O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL)
return head;
ListNode* pre = NULL, *ptr = head, *next;
while(ptr) {
next = ptr->next;
ptr->next = pre;
pre = ptr;
ptr = next;
}
return pre;
}
};
- 思路2:怎么递归来处理?逆转一个链表a[:n],a[k+1:]都已经逆转了。这个时候a[k+2]和a[k]都指向a[k+1]。所以只要a[k+1]指向a[k]。a[k]指向NULL就可以。
- 注意:a[k]一定要指向NULL。返回首节点的地方也有点tricky。
- 复杂度:time O(N), space O(N)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if(head == NULL || head->next == NULL)
return head; // return最后一个节点,也就是逆转后链表的首节点
ListNode* p = reverseList(head->next);
head->next->next = head;
head->next = NULL;
return p;
}
};
92. Reverse Linked List II [medium]
Reverse a linked list from position m to n. Do it in one-pass.
Note: 1 ≤ m ≤ n ≤ length of list.
Example:
Input: 1->2->3->4->5->NULL, m = 2, n = 4
Output: 1->4->3->2->5->NULL
- 思路:首先找到要反转部分的第一个和最后一个节点。要记住第一个节点的前一个节点。把最后一个节点的next设为NULL。然后把中间这部分用上面的方法逆转。之后在连接就可以。
- 注意:
- 逆转部分抽出一个方法,这样变量名不会混乱。可以复用上一问的内容。
- 逆转结束后重新连接要注意一下。
- 复杂度:时间O(n)。空间O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL)
return head;
ListNode* pre = NULL, *ptr = head, *next;
while(ptr) {
next = ptr->next;
ptr->next = pre;
pre = ptr;
ptr = next;
}
return pre;
}
ListNode* reverseBetween(ListNode* head, int m, int n) {
ListNode* dummy = new ListNode(-1);
dummy->next = head;
ListNode* first = dummy, * last = dummy, *pre = NULL, *next = NULL, *tmp = NULL;
while(m--) {
pre = first;
first = first->next;
}
while(n--) {
last = last->next;
next = last->next;
}
last->next = NULL;
tmp = first;
pre->next = reverseList(tmp);
first->next = next;
return dummy->next;
}
};
143. Reorder List [medium]
Given a singly linked list L: L0→L1→…→Ln-1→Ln,
reorder it to: L0→Ln→L1→Ln-1→L2→Ln-2→…
You may not modify the values in the list's nodes, only nodes itself may be changed.
Example 1:
Given 1->2->3->4, reorder it to 1->4->2->3.
Example 2:
Given 1->2->3->4->5, reorder it to 1->5->2->4->3.
- 思路:先找到中点。然后把后半部分逆转。然后再合并两个链表。
- 复杂度:time O(N), space O(1)
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode* reverseList(ListNode* head) {
if (head == NULL || head->next == NULL)
return head;
ListNode* pre = NULL, *ptr = head, *next;
while(ptr) {
next = ptr->next;
ptr->next = pre;
pre = ptr;
ptr = next;
}
return pre;
}
void mergeList(ListNode* first, ListNode* second) {
bool tic = true;
ListNode* next, *ret = first;
while(first && second) {
if (tic) {
next = first->next;
first->next = second;
first = next;
} else {
next = second->next;
second->next = first;
second = next;
}
tic = !tic;
}
}
void reorderList(ListNode* head) {
if (head == NULL || head->next == NULL)
return;
ListNode* slow = head, *fast = head, *second = NULL, *pre = NULL;
while(fast) {
pre = slow;
slow = slow->next;
fast = fast->next;
if(fast) {
fast = fast->next;
}
}
pre->next = NULL;
second = reverseList(slow);
ListNode* ptr2 = second;
mergeList(head, second);
}
};