代码随想录算法训练营第四天| 链表第二天
LeetCode24. 两两交换链表中的节点
题目链接:https://leetcode.cn/problems/swap-nodes-in-pairs/description/
视频讲解:
自己实现
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode *dummyHead = new ListNode(NULL);
dummyHead -> next = head;
ListNode *p = dummyHead, *q = head;
while(q && q -> next) {
ListNode *temp = q -> next;
p -> next = temp;
q -> next = temp -> next;
temp -> next = q;
p = q;
q = q -> next;
}
return dummyHead -> next;
}
};
LeetCode19. 删除链表的倒数第 N 个结点
题目链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/description/
视频讲解:
自己实现
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *dummyHead = new ListNode(NULL);
dummyHead -> next = head;
ListNode *p = dummyHead, *q = dummyHead;
while(n-- && q) {
q = q -> next;
}
while(q && q -> next) {
q = q -> next;
p = p -> next;
}
if(p -> next) p -> next = p -> next -> next;
return dummyHead -> next;
}
};
LeetCode19. 删除链表的倒数第 N 个结点
题目链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/description/
视频讲解:
自己实现
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode *dummyHead = new ListNode(NULL);
dummyHead -> next = head;
ListNode *p = dummyHead, *q = dummyHead;
while(n-- && q) {
q = q -> next;
}
while(q && q -> next) {
q = q -> next;
p = p -> next;
}
if(p -> next) p -> next = p -> next -> next;
return dummyHead -> next;
}
};
题解
面试题 02.07. 链表相交
题目链接:https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/
视频讲解:
自己实现
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
int countA = 0, countB = 0, c = 0;
ListNode *p = headA;
while(p) {
p = p -> next;
countA++;
}
ListNode *q = headB;
while(q) {
q = q -> next;
countB++;
}
q = headB;
p = headA;
if(countA >= countB) {
c = countA - countB;
while(c-- && p) p = p -> next;
}else {
c = countB - countA;
while(c-- && q) q = q -> next;
}
while(q && p) {
cout << p -> val << endl;
cout << q -> val << endl;
if(q == p) {
return p;
}
p = p -> next;
q = q -> next;
}
return NULL;
}
};
LeetCode142.环形链表II
题目链接:https://leetcode.cn/problems/linked-list-cycle-ii/
视频讲解:
自己实现
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode *p = head, *q = head;
while(q != NULL && q -> next != NULL) {
p = p -> next;
q = q -> next -> next;
if(p == q) {
p = head;
while(p != q) {
p = p -> next;
q = q -> next;
}
return p;
}
}
return NULL;
}
};
总结
如何找到环的入口处
slow = x + y
fast = x + n( x + y ) (n >= 1)
因为快指针是慢指针路程的两倍,所以可得等式
2 ( x + y ) = x + n * ( x + y )
化简得
x = n( y + z ) - y
x = ( n - 1 ) * ( y + z ) + z
结合图片理解该等式物理意义,若当 n = 1 时 x = z
注意
- 为什么不是
slow = x + y + k (y + z)
,快指针一定会在慢指针进入环中的第一圈追到,假设慢指针走了1/2
圈,快指针已经走了一圈了,快指针一定在途中超过了 - 为什么是
n >= 1
,举反例,如果n = 0,快指针不可能追上慢指针