代码随想录打卡第四天, 新手自我记录一下刷题历程, 仅为自我打卡使用.
周末较忙, 周六做的题目, 周日记录的博客
题目不难, 捋清楚每次要做的几个步骤就行
比方说 1->2->3->4 这样的一个链表
在节点1要做的几件事分别为:
把1->next指向节点3, (但是第二个节点不能丢, 所以先用一个tmp1存一下节点2)
把3->next指向原本的节点2(也就是刚存的tmp1, 但是节点4不能丢, 所以先用另一个tmp2存一下节点4)
再把2->next指向节点4(也就是刚存的tmp2)
在节点2不需要动作, 在节点3需要重复类似在节点1的操作, 所以每轮操作之后走两步, 最终完成两两交换.
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyHead = new ListNode(0, head);
ListNode* cur = dummyHead;
ListNode* tmp1;
ListNode* tmp2;
while (cur->next != nullptr && cur->next->next != nullptr){
tmp1 = cur->next;
cur->next = cur->next->next;
tmp2 = cur->next->next;
cur->next->next = tmp1;
cur->next->next->next = tmp2;
cur = cur->next->next;
}
return dummyHead->next;
}
};
正常思路是先遍历一次链表得到长度L, 然后删除倒数第n个节点 就要走到从头数第(L-n)节点的位置并删除他的下一个节点
要一次扫描就找到,考虑用双指针, fast和slow初始都指向首元节点, fast先走n个节点, 然后fast和slow一起往后走, 直到fast到达最后一个节点, 此时slow正好处于第(L-n)个节点位置, 删除其下一个节点即可.
这里我实现的时候习惯性的建立了虚拟头节点, 写完之后发现完全没必要, 因为本来也不需要对头节点区分操作, 不过懒得改了.
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyHead = new ListNode(0, head);
ListNode* fast = dummyHead;
ListNode* slow = dummyHead;
for (int i = 0; i < n; ++i){
fast = fast->next;
}
while (fast->next != nullptr){
fast = fast->next;
slow = slow->next;
}
ListNode* tmp = slow->next;
slow->next = slow->next->next;
delete tmp;
return dummyHead->next;
}
};
两个单链表如果相交, 一定是后面的n个节点相同. 如果能找到两者剩余元素相等的节点, 从此处开始用两个指针同时向后移动, 遍历两个链表, 一一比较每步两个指针所指的节点是否相同即可.
所以要先分别遍历两个链表一次得到各自的长度.
这里我的代码里的虚拟头节点也是不必要的, 二刷时候要改正! 越简洁越好.
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* dummyHeadA = new ListNode(0, headA);
ListNode* dummyHeadB = new ListNode(0, headB);
ListNode* curA = dummyHeadA;
ListNode* curB = dummyHeadB;
int sizeA = 0;
int sizeB = 0;
while (curA->next != nullptr){
sizeA++;
curA = curA->next;
}
while (curB->next != nullptr){
sizeB++;
curB = curB->next;
}
curA = dummyHeadA;
curB = dummyHeadB;
if (sizeA >= sizeB){
for (int i = 0; i < sizeA - sizeB; ++i){
curA = curA->next;
}
}
else{
for (int i = 0; i < sizeB - sizeA; ++i){
curB = curB->next;
}
}
while (curA->next != nullptr){
if (curA->next == curB->next){
return curA->next;
}
curA = curA->next;
curB = curB->next;
}
return NULL;
}
};
这题真的好难! 第一次接触链表环的时候完全想不到是这么做的!
这里就不强行分析了, 我是看了leetcode大神题解和carl哥视频之后才完全懂的.
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while (fast != nullptr && fast->next != nullptr){
fast = fast->next->next;
slow = slow->next;
if (fast == slow){
fast = head;
while(fast != slow){
fast = fast->next;
slow = slow->next;
}
return slow;
}
}
return NULL;
}
};
到这随想录的链表部分的主干题目就完成了!
撒花!