[4]-代码随想录算法训练营-day4-链表-part2

发布时间 2023-08-30 01:09:40作者: 缪白(Miubai)

代码随想录算法训练营第四天|链表-part2

1.Leecode 24.两两交换链表中的节点

  1. 题目

  2. 思路

    • 虚拟头节点
    • tmp变量记录
    • 交换
  3. 刷随想录后想法

    • tmp变量需要两个
  4. 实现困难

    • 交换后链表连接逻辑存在错漏
  5. 实现代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* swapPairs(ListNode* head) {
            ListNode* dummyHead = new ListNode(0);  //虚拟头节点
            dummyHead->next = head;
            ListNode* cur = dummyHead;
            ListNode *tmp, *tmp1;
            while(cur && cur->next && cur->next->next){
                tmp = cur->next;
                tmp1= cur->next->next->next;
                cur->next = tmp->next;
                tmp->next->next = tmp;
                tmp->next = tmp1;
                cur =cur->next->next;
            }
            return dummyHead->next;
        }
    };
    
  6. 学习收获

    • 善用dummyHead
    • 编程前,画图计算,逻辑演算,避免存在逻辑错漏

2.LeetCode 19.删除链表倒数第N个节点

  1. 题目

  2. 思路

    • 思路1:暴力,先获取size,再次确定要删除的节点
    • 思路2:栈
    • 思路3:递归
  3. 刷随想录想法

    • 双指针
    • 快指针fast先移动n+1步
    • 慢指针slow,随后同步移动
    • slow指向了待删除节点的前一个节点,执行删除操作即可
  4. 实现困难

    • while循环中,关于fastslow快多少步的问题,老报地址越界问题
  5. 实现代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode() : val(0), next(nullptr) {}
     *     ListNode(int x) : val(x), next(nullptr) {}
     *     ListNode(int x, ListNode *next) : val(x), next(next) {}
     * };
     */
    class Solution {
    public:
        ListNode* removeNthFromEnd(ListNode* head, int n) {
            ListNode *dummyHead = new ListNode(0);
            dummyHead->next = head;
            ListNode *slow = dummyHead;
            ListNode *fast = dummyHead;
            while(n-- && fast){
                fast = fast->next;
            }
            fast = fast->next;
            while(fast){
                fast = fast->next;
                slow = slow->next;
            }
    
            ListNode *tmp = slow->next;
            slow->next = tmp->next;
            delete tmp;
            return dummyHead->next;
        }
    };
    
  6. 学习收获

    • 关于while(n--),先判断n是否为0,再进行减减操作,若n=2,则while循环两次。
    while(n--){ 
      //.....
    }
    //等价于
    while(n){
    	n--;
        //.....
    }
    
    • n----n,运算符在前则先运算,反之则先判断在运算。

3.LeetCode 面试题02.07.链表相交

  1. 题目

  2. 思路

    • 暴力,两层while循环
  3. 刷随想录想法

    • 求长度,位置对齐后比较
  4. 实现困难

    • int lenA, lenB = 0;这里lenA居然没有被初始化为0,然后导致一致过不了样例!!!
  5. 实现代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
            ListNode *curA = headA;
            ListNode *curB = headB;
            int lenA = 0;
            int lenB = 0;
            int count = 0;
    
            while(curA){
                curA = curA->next;
                lenA++;
            }
            while(curB){
                curB = curB->next;
                lenB++;
            }
            //这里一定要先执行cur = head操作
            if(lenA < lenB){
                //lenA > lenB, 交换,让curA表示长的
                curA = headB;
                curB = headA;
                count = lenB - lenA;
            }else{
                curA = headA;
                curB = headB;
                count = lenA - lenB;
            }
    
            while(curA && count--){
                curA = curA->next;
            }
    
            //现在A和B尾部对齐了
            while(curA && curB && curA != curB){
                curA = curA->next;
                curB = curB->next;
            }
            return curA;
        }
    };
    

4.LeetCode 142.环形链表

  1. 题目

  2. 思路

  3. 刷随想录想法

    • 感觉偏向数学问题了
  4. 实现困难

    • 首先是对数学问题的分析
    • 其次是将数学问题编程化
    • 最后,对整个过程还有一点模糊
  5. 实现代码

    /**
     * Definition for singly-linked list.
     * struct ListNode {
     *     int val;
     *     ListNode *next;
     *     ListNode(int x) : val(x), next(NULL) {}
     * };
     */
    class Solution {
    public:
        ListNode *detectCycle(ListNode *head) {
            ListNode *fast = head;
            ListNode *slow = head;
            while(fast && fast->next){
                fast = fast->next->next;
                slow = slow->next;
                
                if(fast == slow){
                    ListNode *index1 = fast;
                    ListNode *index2 = head;
                    while(index1 != index2){
                        index1 = index1->next;
                        index2 = index2->next;
                    }
                    return index1;
                }
            }
            return NULL;
        }
    };