我在代码随想录|写代码Day10之双指针19. 删除链表的倒数第 N 个结点,面试题 02.07. 链表相交,142. 环形链表 II

博主介绍: 27dCnc
专题 : 数据结构帮助小白快速入门

☆*: .。. o(≧▽≦)o .。.:*☆

19. 删除链表的倒数第 N 个结点

题目
我在代码随想录|写代码Day10之双指针19. 删除链表的倒数第 N 个结点,面试题 02.07. 链表相交,142. 环形链表 II_第1张图片

代码

/**
 * 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*dum = new ListNode(0);//虚拟头节点
        dum->next = head;//确定虚拟头节点的位置
        ListNode*fast = head;//快指针
        ListNode*slow = dum;//慢指针
        ListNode*cnt=head;//用cnt用来计数否则不知道要删除哪个节点
        int count=0;//对我们的链表进行计数
        while(cnt){//当我们的指针不为空我们就将指针后移
            cnt=cnt->next;//进行后移操作
            count++;
        }
        int tme = (count-n);//定位我们要删除的元素位置
        while(tme){
            fast = fast->next;//快指针进行移动
            if(fast==nullptr){//判断
                break;//如果我们快指针移动后不判断在移动我们就有可能
            }//遇到我们快指针当前指向为空然后我们慢指针指针我们快指针为空的位置即对为空指针的操作
            slow = slow->next;
            tme--;//计数,为什么不直接放while中因为会出现问题当coun为1为1就无法进行循环
        }
        if(fast!=nullptr){//判断如果空指针不为空那么对slow指针进行操作
            slow->next=fast->next;
        }else{
            slow->next=nullptr;//否则我们直接让slow指针为空即可
        }
        return dum->next;//返回我们的头结点因为我们要删除的元素可能是头结点所以我们要用虚拟头结点
    }
};

思路:删除N个结点
步骤
1.首先这里我推荐大家使用虚拟头结点,这样方便处理删除实际头结点的逻辑
2.定义fast指针和slow指针,初始值为虚拟头结点
3.fast首先走n + 1步 ,为什么是n+1呢,因为只有这样同时移动的时候slow才能指向删除节点的上一个节点(方便做删除操作)
4.fast和slow同时移动,直到fast指向末尾
5.删除slow指向的下一个节点

面试题 02.07. 链表相交

题目
我在代码随想录|写代码Day10之双指针19. 删除链表的倒数第 N 个结点,面试题 02.07. 链表相交,142. 环形链表 II_第2张图片
代码

/**
 * 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* you= headA;
        ListNode* me= headB;
        // 在遇到你之前,我们是俩条平行线,以外不会相遇
        if (you == nullptr || me == nullptr) 
            return nullptr;
        // 兜兜转转,我们的生命轨迹终将出现交点
        while(me!=you){
            // 我们携手与共,即使一个人掉队,也会拉上彼此继续前行
            you = you == nullptr ? headB : you->next;
            me = me == nullptr ? headA : me->next;r
            // 往后余生,你就是我的世界
        }
        return you;
        //即使身处两个世界,但只要以相同的速度双向奔赴,就一定会相遇。
        //两人同时以相同的速度走自己的路,走完自己的路之后走对方的路,两者有缘则相遇,
        //相遇则结束长跑,若无缘则同时走到“空”,跳出感情的死循环。
    }
};

142. 环形链表 II

题目
我在代码随想录|写代码Day10之双指针19. 删除链表的倒数第 N 个结点,面试题 02.07. 链表相交,142. 环形链表 II_第3张图片

代码

/**
 * 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!=nullptr&&fast->next!=nullptr){
            //即使身处两个世界,以不相同的速度双向奔赴,但只要在同一恋爱循环中,就一定会相遇。
            slow = slow->next;
            fast = fast->next->next;
            //在命运的某一时刻我们登入的婚姻的殿堂
            if(slow==fast){
                //在我们相遇的哪个时刻脑中回忆着过往
                ListNode*cnt = slow; 
                ListNode*cur = head;
                while(cur!=cnt){
                    //从相识到相知彼此断靠近
                    cur=cur->next;
                    cnt = cnt->next;
                }
                //直到回忆道我们的青涩告白返回我们当初最真挚的情感
                return cur;
            }
        }
        //尽管我们没有进入恋爱的循环我们都有着彼此的故事
        return nullptr;
    }
};

如果此文对你有帮助的话,欢迎关注、点赞、⭐收藏、✍️评论,支持一下博主~

你可能感兴趣的:(链表,数据结构,c++,笔记,算法)