今天的第一题是两两交换链表中的节点https://leetcode.cn/problems/swap-nodes-in-pairs/description/直接找卡哥代码随想录。所幸听了一遍自己就敲出来了,看来代码水平确实涨了。
class Solution {
public:
ListNode* swapPairs(ListNode* head) {
ListNode* dummyhead = new ListNode(0);
dummyhead->next = head;
ListNode* cur = dummyhead;
while(cur->next != NULL && cur->next->next != NULL){
ListNode* tmp = cur->next;
ListNode* tmp1 = cur->next->next->next;
cur->next = cur->next->next;
cur->next->next = tmp;
cur->next->next->next = tmp1;
cur = cur->next->next;
}
return dummyhead->next;
}
};
第二题是删除倒数第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(0);
dummyhead->next = head;
ListNode* cur = dummyhead;
int count = 0;
while(cur->next != NULL){
cur = cur->next;
count++;//求链表长度
}
int m = count - n ;//倒数元素的正数位置
ListNode* cur1 = dummyhead;
while(m--){
cur1 = cur1->next;
}
cur1->next = cur1->next->next;
return dummyhead->next;
}
};
然后看的卡哥思路代码随想录,还是用双指针,感觉这种思路都不太好想。
class Solution {
public:
ListNode* removeNthFromEnd(ListNode* head, int n) {
ListNode* dummyhead = new ListNode(0);
dummyhead->next = head;
ListNode* fast = dummyhead;
ListNode* slow = dummyhead;
n++;
while(n--&&fast != NULL){
fast = fast->next;
}
while(fast != NULL){
fast = fast->next;
slow = slow->next;
}
slow->next = slow->next->next;
return dummyhead->next;
}
};
这种方法很巧妙的只用了一次遍历,简单了许多。
第三题是链表相交https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/想确定是否相交,只用看两个链表的最后一个元素值是否相同,如果最后一个也不相同,那肯定没戏。但是写出来的代码报错,原因是没有考虑到两个链表的长度不同,都从头移动是无效的。
卡哥代码本质上也是先调整两个指针的位置,使之对齐。
class Solution {
public:
ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
ListNode* curA = headA;
ListNode* curB = headB;
int lenA = 0, lenB = 0;
while (curA != NULL){
lenA++; curA = curA->next;
}
while(curB != NULL){
lenB++; curB = curB->next;
}
curA = headA;
curB = headB;
if(lenB > lenA){
swap(lenA, lenB);
swap(curA, curB);
}
int gap = lenA - lenB;
while(gap--){curA = curA->next;}
while(curA != NULL){
if(curA == curB){return curA;}
curA = curA->next;
curB = curB->next;
}
return NULL;
}
};
第四题是接触的第一道中等题环形链表https://leetcode.cn/problems/linked-list-cycle-ii/description/直接上卡哥解析代码随想录,思路很妙,用了几何知识,构造两个指针相互追赶。这个题很好。虽然自己没写出来,但是依然感觉学到了东西。
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
ListNode* fast = head;
ListNode* slow = head;
while(fast != NULL && fast->next != NULL){
slow = slow->next;
fast = fast->next->next;
if(slow == fast){
ListNode* index1 = fast;
ListNode* index2 = head;
while(index1 != index2){
index1 = index1->next;
index2 = index2->next;
}
return index2;
}
}
return NULL;
}
};
这周的周末把链表章节学完了, 最开心的是有些题是自己单独做出来的,对于我这种菜鸡来说,第一遍显然不能完全吃透那些绕弯的方法思路,但是学会了链表的基础操作,dummyhead的运用,也算是小有收获了