24. 两两交换链表中的节点
再次感觉到虚节点dummy的妙用,这里很容易想到用三个指针去表示节点的移动。最后要注意返回的不是head而是dummy>next,因为整体是节点的移动所以初始头节点已经发生变化。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(!head) return nullptr;
auto* dummy = new ListNode(0,head);
auto* left = dummy;
ListNode* mid, * right;
while(left->next && left->next->next) {
mid = left->next;
right = mid->next;
auto* temp = right->next;
left->next = right;
right->next = mid;
mid->next = temp;
left = mid;
}
return dummy->next;
}
};
19.删除链表的倒数第N个节点
整体思路很明确,倒数第n个节点 = 第二个指针比第一个指针先走n - 1步,然后两个指针一起跑直到第二个指针直到末尾。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode() : val(0), next(nullptr) {}
* ListNode(int x) : val(x), next(nullptr) {}
* ListNode(int x, ListNode *next) : val(x), next(next) {}
* };
*/
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummy = new ListNode(0,head);
auto* left = dummy;
auto* right = dummy;
while(n--){
right = right->next;
}
while(right->next){
left = left->next;
right = right->next;
}
auto* temp = left->next;
left->next = temp->next;
delete temp;
return dummy->next;
}
};
链表相交
142.环形链表II
这题直觉是双指针法,但是摸不清具体规律。看了答案,总结下来就是先让快慢指针相遇,再让满指针和链表头开始移动的指针相遇,他们所在地点是入口函数处
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* dummy = new ListNode(0,head);
auto* slow = head;
auto* fast = head;
while(1) {
if(!fast || !fast->next) return nullptr;
fast = fast->next->next;
slow = slow->next;
if(fast == slow) {
break;
}
}
while(slow != head){
slow = slow->next;
head = head->next;
}
return head;
}
};