#打卡记录
24. 两两交换链表中的节点
按图中这个顺序做,很清晰,很省脑子,记录一下
关于虚拟头结点,这个是为了统一处理操作,正常移除操作时,头节点的操作和其他节点的不一致,引入虚拟头节点后可统一操作。代码表示:ListNode* ans = new ListNode(0, head);
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
if(head == nullptr) return nullptr;
int temp = 0;
int flag = 0;
ListNode* ans = new ListNode(0, head);
ListNode* cur = ans;
while(cur->next != nullptr && cur->next->next != nullptr){
ListNode* temp1 = cur->next;
ListNode* temp2 = cur->next->next->next;
cur->next = temp1->next;
cur->next->next = temp1;
cur->next->next->next = temp2;
cur = cur->next->next;
}
return ans->next;
}
};
19.删除链表的倒数第N个节点
双指针的经典应用,如果要删除倒数第n个节点,让fast移动n步,然后让fast和slow同时移动,直到fast指向链表末尾。删掉slow所指向的节点就可以了。
由于使用了虚拟头节点,所以操作需要变成fast先移动n+1步。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* ans = new ListNode(0, head);
ListNode* fast = ans;
ListNode* slow = ans;
while(n != 0 && fast->next != nullptr){
fast = fast->next;
n--;
}
fast = fast->next;
while(fast != nullptr){
fast = fast->next;
slow = slow->next;
}
ListNode* node = slow->next;
slow->next = slow->next->next;
delete node;
return ans->next;
}
};
面试题 02.07. 链表相交
A,B链表假设相交,则可分割为a+c和b+c,c为相交后的部分,则可得出等式
a+c+b = b+c+a,即走完A链表再走B链表单独的部分的路程,和走完B链表再走A链表单独的部分的路程是相等的。
假设不相交,则a+b = b+a,两根指针在遍历完A,B链表后,会同时位于链表的末尾——null的位置。
所以可以得出以下代码。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* cur1 = headA;
ListNode* cur2 = headB;
while(cur1 != cur2){
if(cur1 == NULL){
cur1 = headB;
}
else{
cur1 = cur1->next;
}
if(cur2 == NULL){
cur2 = headA;
}
else{
cur2 = cur2->next;
}
}
return cur1;
}
};
142.环形链表II
同样是快慢指针,但这里需要注意fast和slow之间差的“速度”是多少,因为数据是离散的,不能完全按照跑道套圈来理解,如果速度差设置的不对可能导致两者无法相遇,目前已知fast一次走两格,slow一次走一格,即
fast = fast->next->next;
slow = slow->next;
这个速度差是可行的。
找到入口的方法:从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
ListNode* start = head;
do{
if(fast == NULL || fast->next == NULL){
return NULL;
}
fast = fast->next->next;
slow = slow->next;
}while(fast != slow);
while(slow != start){
slow = slow->next;
start = start->next;
}
return start;
}
};