首页 > 其他分享 >leetcode刷题day4|链表部分(24. 两两交换链表中的节点 、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II)

leetcode刷题day4|链表部分(24. 两两交换链表中的节点 、19.删除链表的倒数第N个节点、面试题 02.07. 链表相交、142.环形链表II)

时间:2024-08-31 16:50:43浏览次数:12  
标签:面试题 ListNode cur head next 链表 null 节点

前言:链表练习的第二天,对链表的理解加深了

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

这个题一开始的思路是用cur和next两个指针来做,但是绕来绕去绕迷糊了,最后超时了。把错误的代码放在下面警醒大家:
主要问题出现在这两行代码,next.next发生了更改。
next.next=next.next.next;
next.next.next=next;

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy=new ListNode(0,head);
        ListNode cur=dummy;
        ListNode next=head;
        while(next!=null && next.next!=null){
            cur.next=next.next;
            next.next=next.next.next;
            next.next.next=next;//这一步有问题因为next.next已经被更改了
            cur=next;
            next=next.next;
        }
        return dummy.next;
    }
}

这个题还是3个指针清晰一些。代码如下:

class Solution {
    public ListNode swapPairs(ListNode head) {
        ListNode dummy=new ListNode(0,head);
        ListNode cur=dummy;
        while(cur.next!=null && cur.next.next!=null){
            ListNode node1=cur.next;
            ListNode node2=cur.next.next;
            cur.next=node2;
            node1.next=node2.next;
            node2.next=node1;
            cur=cur.next.next;
        }
        return dummy.next;
    }
}

递归版本想不出来,看了一下答案写出来了。
该递归也是反向交换,先到达最后两个节点交换完回到上一层交换上两个节点。
代码如下:

class Solution {
    public ListNode swapPairs(ListNode head) {
        if(head==null || head.next==null){
            return head;
        }
        ListNode next=head.next;
        ListNode swapHead=swapPairs(next.next);
        head.next=swapHead;
        next.next=head;
        return next;
    }
}

总结:该递归的关键是理解最后一层head=null,达到边界条件,返回值swapHead=null,此时交换不需要指定swapHead下一个指向睡,只需要将head指向swapHead,next指向head即可。

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

思路:该题使用快慢指针来做,让fast先走n步,再一起往前走,当fast为null时,slow刚好指到要删除节点的前一个。
注意:slow删除节点时需要判断slow.next是否为null,避免空指针异常
代码如下:

class Solution {
    public ListNode removeNthFromEnd(ListNode head, int n) {
        ListNode dummy=new ListNode(0,head);
        ListNode fastNode=dummy;
        ListNode slowNode=dummy;
        for(int i=0;i<n+1;i++){
            fastNode=fastNode.next;
        }
        while(fastNode!=null){
            fastNode=fastNode.next;
            slowNode=slowNode.next;
        }
        if(slowNode.next!=null){
            slowNode.next=slowNode.next.next;
        }
        return dummy.next;
    }
}

面试题 02.07. 链表相交

思路:链表A和链表B存在差值,首先先让长链表将指针移到差值的位置,使得链表AB的尾端对齐,再一起向前走知道两个指针指向同一位置。
代码入下:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        int lengthA=0,lengthB=0;
        ListNode pointA=headA,pointB=headB;
        while(pointA!=null){
            pointA=pointA.next;
            lengthA++;
        }
        while(pointB!=null){
            pointB=pointB.next;
            lengthB++;
        }
        pointA=headA;
        pointB=headB;
        int diff=0;
        if(lengthA>lengthB){
            diff=lengthA-lengthB;
            for(int i=0;i<diff;i++){
                pointA=pointA.next;
            }
        }else if(lengthA<lengthB){
            diff=lengthB-lengthA;
            for(int i=0;i<diff;i++){
                pointB=pointB.next;
            }
        }
        while(pointA!=pointB && pointA!=null){
            pointA=pointA.next;
            pointB=pointB.next;
        }
        return pointA;
    }
}

合并链表的方法更加巧妙一些,其原理是如果将两个长度不同的链表连在一起长度就相同了,A+B和B+A长度相同且后端对齐,可直接遍历两个合并的链表,如果指针对应相等则为相交的点。
注意:不用考虑元素相不相同的问题,因为比较的是节点相不相同,即节点的地址是否一致。
代码如下:

public class Solution {
    public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode point1=headA;
        ListNode point2=headB;
        while(point1!=point2){
            if(point1==null){
                point1=headB;
            }else{
                point1=point1.next;
            }
            if(point2==null){
                point2=headA;
            }else{
                point2=point2.next;
            }
        }
        return point1;
    }
}

142.环形链表II

思路:这个题之前做过,用快慢指针。快指针每次走两步,慢指针每次走一步。搞清x(head到环开始的距离) y(环开始到相遇的距离) z(相遇到环结束的距离)以及走的步数m的关系是关键。最重要得到x和m的关系
假设 fast多走一圈与x相遇,由x+y+y+z=2(x+y)得x=z;
即使多圈后相遇,也可由x+y+n(y+z)=2(x+y)得x=z;
也就是说从相遇点和head同时出发,两个指针同时到达环开始的位置。
步骤如下:
1、先找到相遇点;
2、从相遇点和起点同时出发两个指针;
3、一起向前走并记录步数,相遇时即为环的位置。
代码如下:

public class Solution {
    public ListNode detectCycle(ListNode head) {
        ListNode p1=head,p2=head;
        while(p1!=null && p1.next!=null){
            p1=p1.next.next;
            p2=p2.next;
            if(p1==p2){
                ListNode index1=p1;
                ListNode index2=head;
                while(index1!=index2){
                    index1=index1.next;
                    index2=index2.next; 
                }
                return index1;
            }
        }
        return null;
    }
}

标签:面试题,ListNode,cur,head,next,链表,null,节点
From: https://blog.csdn.net/m0_51007517/article/details/141752606

相关文章

  • leetcode刷题day3|链表部分( 203.移除链表元素、707.设计链表、206.反转链表)
    前言:链表部分之前刷过一些题,掌握的还可以,希望可以顺利把这部分题刷完。203.移除链表元素思路:自己创建一个头节点,使新的头节点指向旧的头节点。错误尝试:一开始考虑的比较复杂,设置了指针pre,能够想到直接比较cur.next.val和val的值会使代码更加简洁,但也要注意想清楚如果删除......
  • 一些JAVA面试题
    前言由于这段时间经常性的找工作找工作找工作,然后面试题问的也比较多,我就想着对这个进行一些整合,基本都是我面试的时候问过的一些问题,三年经验的JAVA开发,可能答案有些不太准确,请多多包涵和见谅;线上面试题基础类型判断publicstaticvoidmain(String[]args){//......
  • 数据结构-单链表-详解-2
    数据结构-单链表-详解-21.前言2.创建新结点3.头插与尾插3.1头插3.2尾插空链表找尾4.头删与尾删4.1头删4.2尾删1.前言在数据结构-单链表-详解-1中,我们不仅了解了单链表的基本概念,还掌握了如何创建和打印单链表。今天,我将详细讲解如何对单链表进行头尾部的插入、......
  • Python自动化测试面试题总结_pytest框架面试题
    ???16、请用python脚本实现从1到100的求和。???17、编写一个匿名函数,使其能够进行加法运算,例如说输入1,2能计算结果为3???18、list_1=[1,2,1,2,15,4,3,2,1,2],去除list_1的重复值,并且从大到小排序。???19、统计字符串中的单词个数,这里的单词指的是连续的不是空格的......
  • 大厂产品经理面试:阿里、字节、百度、腾讯、拼多多等全国顶级大厂面试题一网打尽!
    在互联网行业蓬勃发展的今天,产品经理作为连接技术、设计和市场的核心角色,其重要性日益凸显。想要进入国内顶尖的互联网大厂,如阿里巴巴、字节跳动、百度、腾讯、拼多多等,产品经理岗位的面试无疑是一场硬仗。本文将为你揭秘这些大厂的产品经理面试真题,并提供参考答案思路,助你顺利......
  • 单链表应用
    基于单链表实现通讯录项目//Contact.c#define_CRT_SECURE_NO_WARNINGS1#include"contact.h"#include"list.h"//初始化通讯录voidInitContact(contact**con){ con=NULL; }//添加通讯录数据voidAddContact(contact**con){ PeoInfoinfo; printf("addres......
  • 单链表
    目录1.链表的概念及结构2.单链表的实现3.链表的分类                        1.链表的概念及结构概念:链表是一种物理存储结构上非连续、非顺序的存储结构,数据元素的逻辑顺序是通过链表中的指针链接次序实现的 链......
  • 代码随想录算法day4 - 链表2
    题目124.两两交换链表中的节点给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。示例1:输入:head=[1,2,3,4]输出:[2,1,4,3]示例2:输入:head=[]输出:[]示例3:输入:head=[1]输出:[1]......
  • list容器---深入探索STL中的双向链表
    目录一、引言二、list容器原理三、list容器的常用操作  1.创建list容器  2.添加元素  3.删除元素  4.访问元素  5.遍历list容器四、list容器的优缺点五、实际应用场景六、总结        本文将详细介绍C++STL中的list容器,包括其原理、常用......
  • 代码随想录算法训练营,8月30日 | 203.移除链表元素, 707.设计链表, 206.反转链表
    链表理论基础1.单链表:数据域和指针域(指向下一个结点的位置)组成,头结点,结尾为空指针;双链表:多了一个指向前一个结点的指针;循环链表:结尾指向头结点。2.链表在内存中的存储不是顺序的,跟数组不同,要找一个数据只能通过前一个数据来找,所有这就导致链表的查询比数组麻烦,但是插入删除数据......