代码随想录刷题第四天

今天的第一题是两两交换链表中的节点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的运用,也算是小有收获了

你可能感兴趣的:(leetcode)