声明一个虚拟头节点和当前指针。当前指针初始为虚拟头节点。
遍历链表,交换指针的下一节点和下下节点。如果为节点个数为奇数,最后一个不做操作。
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 ListNode* swapPairs(ListNode* head) { 14 ListNode* preHead = new ListNode(-1); 15 preHead->next = head; 16 ListNode* curr = preHead; 17 while(curr != nullptr && curr->next != nullptr){ 18 ListNode* tmp = curr->next; 19 // 如果节点个数为奇数,最后一个跳出 20 if(tmp->next == nullptr) break; 21 curr->next = tmp->next; 22 tmp->next = curr->next->next; 23 curr->next->next = tmp; 24 // 交换完成后指针后移两位 25 curr = curr->next->next; 26 } 27 return preHead->next; 28 } 29 };
声明虚拟头节点,快慢指针都指向虚拟头节点,先将快指针移动n次
遍历链表,直到快指针指向末尾,此时慢指针下一个就是要删除的节点
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode() : val(0), next(nullptr) {} 7 * ListNode(int x) : val(x), next(nullptr) {} 8 * ListNode(int x, ListNode *next) : val(x), next(next) {} 9 * }; 10 */ 11 class Solution { 12 public: 13 ListNode* removeNthFromEnd(ListNode* head, int n) { 14 ListNode* dummyNode = new ListNode(0); 15 dummyNode->next = head; 16 ListNode* fast = dummyNode; 17 ListNode* slow = dummyNode; 18 while(n--){ 19 fast = fast->next; 20 } 21 while(fast->next!=nullptr){ 22 slow = slow->next; 23 fast = fast->next; 24 } 25 // 删除slow->next 26 ListNode* tmp = slow->next; 27 slow->next = slow->next->next; 28 delete tmp; 29 return dummyNode->next; 30 } 31 };
分别求出两个链表的长度,然后末尾对齐。
较短的指针指向头节点,较长的指针后移长度差,使两个链表距离末尾长度相同。
最后挨个比较当前节点是否相同,相同则返回。到最后都不同则返回空。
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) { 12 // A,B的长度 13 int m = 0,n = 0; 14 ListNode* currA = headA; 15 ListNode* currB = headB; 16 while(currA != nullptr){ 17 currA = currA->next; 18 m++; 19 } 20 while(currB != nullptr){ 21 currB = currB->next; 22 n++; 23 } 24 25 // 末尾对齐. 26 currA = headA; 27 currB = headB; 28 if(m > n){ 29 int tmp = m - n; 30 while(tmp--){ 31 currA = currA->next; 32 } 33 }else{ 34 int tmp = n - m; 35 while(tmp--){ 36 currB = currB->next; 37 } 38 } 39 while(currA != currB){ 40 if(currA == nullptr) return nullptr; 41 currA = currA->next; 42 currB = currB->next; 43 } 44 return currA; 45 } 46 };
快慢指针找到是否有环以及相遇位置。若没环则返回null
此时,设第一次入环位置为x,相遇位置距离x为y,再次到入环位置为距离为z
则慢指针走了x+y;快指针走了x+y+n(y+z)
同时快指针走了慢指针的两倍
则有2(x+y) = x+y + n(y+z)
=>x+y = n(y+z)
为了求x
则x = n(y+z) - y
=>x = n(y+z)-y-z+z
=>x = n(y+z)-(y+z)+z
=>x = (n-1)(y+z) + z
由于y+z是一个环,n是第n圈相遇,则说明 x = z
这时一个指针在相遇位置出发,另一个在起始位置出发,再次相遇的位置就是第一次相遇的点
1 /** 2 * Definition for singly-linked list. 3 * struct ListNode { 4 * int val; 5 * ListNode *next; 6 * ListNode(int x) : val(x), next(NULL) {} 7 * }; 8 */ 9 class Solution { 10 public: 11 ListNode *detectCycle(ListNode *head) { 12 ListNode* fast = head; 13 ListNode* slow = head; 14 while(fast != nullptr && fast->next != nullptr){ 15 fast = fast->next->next; 16 slow = slow->next; 17 if(fast == slow){ 18 // 一个指针在相遇节点处开始移动,同时在另一指针在头节点开始移动 19 // 相遇位置就是第一次入环的位置 20 fast = head; 21 while(fast!=slow){ 22 fast = fast->next; 23 slow = slow->next; 24 } 25 return fast; 26 } 27 } 28 return nullptr; 29 } 30 };
浙公网安备 33010602011771号