刷题日记 DAY4
链表
leetcode 203 移出链表元素
双指针
本题使用两个指针,前面的指针要比后面的指针多n个偏移量,这样当前面的指针指向链表的末尾时,后面的指针就指向了要删除的元素,但是删除元素需要获取该元素前面的值,解决办法就是前面的指针再多偏移一个。
P.S.关于有关链表的插入与删除操作尽量使用一个虚拟头节点,这样可以使链表每个位置的操作统一化
ListNode* removeElements(ListNode* head, int val) {
ListNode* dummyHead = new ListNode(0);
dummyHead->next = head;
ListNode* cur = dummyHead;
while (cur->next != nullptr) {
if (cur->next->val == val) {
ListNode* tmp = cur->next;
cur->next = cur->next->next;
delete tmp;
}
else {
cur = cur->next;
}
}
head = dummyHead->next;
delete dummyHead;
return head;
}
leetcode 142 环形链表-ii
双指针
本题的要点在于如何推理出相遇的位置。两个指针同时从头节点出发,慢指针每一移动一个单位,快指针每次移动2个单位,如果该链表成环,定会在环内相遇。现设头节点到环入口的距离为x,环入口到相遇点的距离为y,相遇点再到环入口的距离为z,那么在相遇的时候,慢指针所走的距离为x+y,快指针所走的距离为x+n(y+z)+y,又因为快指针每次移动两个单位,而慢指针每次移动一个单位,故相同时间内快指针移动的单位的数量为慢指针的两倍,可推出2(x+y)=x+n(y+z)+y,因要求得x,化简提取x后可推出x=(n-1)(y+z)+z,其中y+z为圆周,故可设n=0,得到x=z,也就是说一个指针从头节点出发,另一个指针从相遇点出发,两个指针一相同的速度前进,相遇点就是环入口。
关于为什么快指针一定会在一圈内追上慢指针的问题:假设快慢指针一起在进入环入口,快指针的速度时慢指针的两倍,在下一次相遇时就在慢指针的第一圈结束,而真实的情况是快指针一定不慢于慢指针进如环中,故一定会在第一圈追上慢指针。
ListNode *detectCycle(ListNode *head) {
ListNode* slow = head;
ListNode* fast = head;
while (fast != nullptr && fast->next != nullptr) {
slow = slow->next;
fast = fast->next->next;
if (slow == fast) {
slow = head;
while (slow != fast) {
slow = slow->next;
fast = fast->next;
}
return slow;
}
}
return nullptr;
}
浙公网安备 33010602011771号