首页 > 编程语言 >代码随想录算法训练营第四天|24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,面试题 02.07. 链表相交,142.环形链表II

代码随想录算法训练营第四天|24. 两两交换链表中的节点,19.删除链表的倒数第N个节点,面试题 02.07. 链表相交,142.环形链表II

时间:2024-09-29 12:48:14浏览次数:9  
标签:dummyHead ListNode cur 随想录 next 链表 节点

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

文章链接:https://programmercarl.com/0024.两两交换链表中的节点.html#思路
视频讲解:https://www.bilibili.com/video/BV1YT411g7br
代码链接:https://leetcode.cn/problems/swap-nodes-in-pairs/

此题注意点:注意由于交换节点,head已经变换了位置,故最终不能直接返回head作为最终的答案,而应该返回dummyHead->next
此题思路:

class Solution {
public:
    ListNode* swapPairs(ListNode* head) {
        ListNode* dummyHead=new ListNode(0);
        ListNode* cur=dummyHead;
        dummyHead->next=head;
        while(cur->next!=nullptr&&cur->next->next!=nullptr){
            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;
        }
        ListNode* headp=dummyHead->next; //不能直接返回head,此时的head位置已经被改变
        delete dummyHead;
        return headp;
    }
};

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

文章链接:https://programmercarl.com/0019.删除链表的倒数第N个节点.html#思路
视频链接:https://www.bilibili.com/video/BV1vW4y1U7Gf
题目链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/

这个题最开始我遍历了两边链表,题解如下:

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyHead=new ListNode(0);
        dummyHead->next=head;
        ListNode* cur=dummyHead;
        ListNode* cur1=dummyHead;
        int size=0;
        while(cur1->next!=nullptr){
            size++;
            cur1=cur1->next;
        }
        int x=size-n;
        while(x--){
            cur=cur->next;
        }
        ListNode* tmp=cur->next;
        cur->next=cur->next->next;
        delete tmp;
        return dummyHead->next;
    }
};

接下来尝试快慢指针:
思路:对于倒数第n步,如果让快指针先走n步,那么两个指针之间的步数差即为n

class Solution {
public:
    ListNode* removeNthFromEnd(ListNode* head, int n) {
        ListNode* dummyHead=new ListNode(0);
        dummyHead->next=head;
        ListNode* f=dummyHead;
        ListNode* s=dummyHead;
        //让f先走n步
        while(n--){
            f=f->next;
        }
        //接着两个一起走,直到f->next为空
        while(f->next!=nullptr){ //注意这里如果写f!=nullptr就错了,因为我们要得到待删除节点的前一个位置的指针
            f=f->next;
            s=s->next;
        }
        ListNode* tmp=s->next;
        s->next=s->next->next;
        delete tmp;
        return dummyHead->next;
    }
};

面试题 02.07. 链表相交

文章链接:https://programmercarl.com/面试题02.07.链表相交.html
题目链接:https://leetcode.cn/problems/intersection-of-two-linked-lists-lcci/description/

思路:
这个题返回的是两个链表后面相交的子链表(表示A,B两个链表最后所得的子链表长度一定相等),故一开始就要让链表长的指针后移,使得两个链表起始的时候指针后面的子链表长度相等。
易错:链表相交是指两个链表在某一个节点处 共享同一段内存位置,即从该节点开始,两个链表之后的节点完全相同(包括地址)。并不是根据节点的值判断,而是两个链表的节点对象需要实际重叠。

class Solution {
public:
    ListNode *getIntersectionNode(ListNode *headA, ListNode *headB) {
        ListNode* a=headA;
        ListNode* b=headB;
        ListNode* curA=headA;
        ListNode* curB=headB;
        int sizeA=0;
        int sizeB=0;
        while(a!=nullptr){
            sizeA++;
            a=a->next;
        }
        while(b!=nullptr){
            sizeB++;
            b=b->next;
        }
        if(sizeA>sizeB){
            int diff=sizeA-sizeB;
            while(diff--){
                curA=curA->next;
            }
        }
        else if(sizeA<sizeB){
            int diff=sizeB-sizeA;
            while(diff--){
                curB=curB->next;
            }
        }
        while(curA!=nullptr){
            if(curA==curB){  //注意不能写成curA->val==curB->val(内存位置也要一样)
                return curA;
            }
            curA=curA->next;
            curB=curB->next;
        }
        return NULL;
    }
};

142.环形链表II

文章链接:https://programmercarl.com/0142.环形链表II.html#思路
视频讲解:https://www.bilibili.com/video/BV1if4y1d7ob
题目链接:https://leetcode.cn/problems/linked-list-cycle-ii/description/

简要思路:1.判断是否有环:相遇即有环(对于slow来说,fast是一个节点一个节点的靠近slow的)
2.有环找入口(详细见代码随想录):相遇节点处,定义一个指针index1,在头结点处定一个指针index2;x=(n-1)C+z ===> x=(n-1)(x+y)+z

class Solution {
public:
    ListNode *detectCycle(ListNode *head) {
        ListNode* f=head;
        ListNode* s=head;
        //f != NULL 确保快指针当前节点不是空指针。
        //f->next != NULL 确保快指针可以继续向前跳两步,防止越界访问 NULL 指针。
        while(f!=NULL&&f->next!=NULL){  
            f=f->next->next;
            s=s->next;
            if(s==f){  //相遇就开始找环入口
                ListNode* index1=f;  //相遇点
                ListNode* index2=head;   //head头节点
                while(index1!=index2){
                    index1=index1->next;
                    index2=index2->next;
                }
                return index1;
            }
        }
        return NULL;
    }
};

标签:dummyHead,ListNode,cur,随想录,next,链表,节点
From: https://www.cnblogs.com/VickyWu/p/18439462

相关文章

  • 代码随想录算法训练营Day16 | 513.找树左下角的值、112.路径总和、113.路径总和Ⅱ、10
    目录513.找树左下角的值112.路径总和113.路径总和Ⅱ106.从中序与后序遍历序列构造二叉树105.从前序与中序遍历序列构造二叉树513.找树左下角的值题目513.找树左下角的值-力扣(LeetCode)给定一个二叉树的根节点root,请找出该二叉树的最底层最左边节点的值。假......
  • 21_合并两个有序链表
    21_合并两个有序链表【问题描述】将两个升序链表合并为一个新的升序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。示例一:输入:l1=[1,2,4],l2=[1,3,4]输出:[1,1,2,3,4,4]示例二:输入:l1=[],l2=[]输出:[]示例三:输入:l1=[],l2=[0]输出:[0]......
  • 链表高频题
    链表高频题160.相交链表#include<vector>#include<iostream>#include<algorithm>structListNode{intval;ListNode*next;ListNode(intx):val(x),next(NULL){}};classSolution{public:ListNode*getIntersectionNode(Li......
  • 代码随想录算法训练营Day03-链表 | LC203移除链表元素、LC707设计链表、LC206反转链表
    目录前言LeetCode203.移除链表元素思路完整代码LeetCode707.设计链表思路完整代码LeetCode206.反转链表思路完整代码今日总结前言拖延症犯了,哈哈,拖了一天LeetCode203.移除链表元素给你一个链表的头节点head和一个整数val,请你删除链表中所有满足Node.val......
  • 代码随想录算法训练营第三天|203.移除链表元素,707.设计链表,206.反转链表
    203.移除链表元素文章链接:https://programmercarl.com/0203.移除链表元素.html#算法公开课视频讲解:https://www.bilibili.com/video/BV18B4y1s7R9题目出处:https://leetcode.cn/problems/remove-linked-list-elements/卡哥在这里讲解了为什么要使用虚拟头节点,以及使用和不使......
  • 面试题 02.07. 链表相交
    明天回家喽,最近在学习的瓶颈期,感觉学的东西好难,有厌学的心理,但是我相信过了这段煎熬的时期,就好了。classSolution{public:ListNode*getIntersectionNode(ListNode*headA,ListNode*headB){intna=0,nb=0;ListNode*tempA=headA;L......
  • /sys/kernel/debug/binder/目录下主要节点含义
    /sys/kernel/debug/binder/目录下主要节点含义state显示binder设备的整体状态信息包括进程数量、线程数量、待处理事务数量等stats展示binder操作的统计信息如事务数量、内存使用情况等transactions列出当前正在处理的binder事务包括发送方、接收方、数据大小......
  • 链表分割 1.2版本
    现有一链表的头指针ListNode* pHead,给一定值x,编写一段代码将所有小于x的结点排在其余结点之前,且不能改变原来的数据顺序,返回重新排列后的链表的头指针。思路:大致可以分为两个区域来存储数据:区域一存储小于36的节点,区域二存储大于36的节点.可以将这两个区域视为两个链表......
  • 算法训练营第三天| 203.移除链表元素、707.设计链表、206.反转链表
    203.移除链表元素状态:完成个人思路:首先令head符合条件,之后判断这个head是否为空,空的话返回空节点;非空的话继续进行。令pre=head;cur=head->next,只要cur非空,就判断cur的值的情况,如果需要删除,就改变pre->next和cur;如果不需要删除就继续检查下一个。看完讲解视频之后的想法:我......
  • 代码随想录算法训练营第三天 | 熟悉链表
    链表的存储方式数组是在内存中是连续分布的,但是链表在内存中可不是连续分布的。链表是通过指针域的指针链接在内存中各个节点。所以链表中的节点在内存中不是连续分布的,而是散乱分布在内存中的某地址上,分配机制取决于操作系统的内存管理。链表的定义template<typenameT>......