【数据结构练习】链表面试题集锦二

2023-09-21 23:14:04

目录

前言:

1.链表分割

2.相交链表

 3.环形链表

 4.环形链表 II


前言:

数据结构想要学的好,刷题少不了,我们不仅要多刷题,还要刷好题!为此我开启了一个必做好题锦集的系列,每篇大约5题左右。此为第二篇选择题篇,该系列会不定期更新敬请期待!


1.链表分割

 代码:

public class Partition {
       public ListNode partition(ListNode head, int x) {
       if(head==null)
       {
           return null;
       }
        ListNode cura1=null;
        ListNode curb1=null;
        ListNode cura2=null;
        ListNode curb2=null;
        ListNode cur=head;
        while (cur!=null){
            if(x>cur.val){
                if(cura1==null){
                    cura1=cur;
                    curb1=cur;
                }else{
                    curb1.next=cur;
                    curb1=curb1.next;
                }
            }else{
                if(cura2==null){
                    cura2=cur;
                    curb2=cur;
                }else{
                    curb2.next=cur;
                    curb2=curb2.next;
                }
            }
            cur=cur.next;
        }
        if(cura1==null){
            return cura2;
        }
        curb1.next=cura2;
        if(curb2!=null){
            curb2.next=null;
        }
        return cura1;
    }
}

解析:

示例1:

(1)

 (2)

(3) 

(4) 

示例2: 

示例3:

(1)

 (2)


2.相交链表

160. 相交链表icon-default.png?t=N7T8https://leetcode.cn/problems/intersection-of-two-linked-lists/ 

 

 

 方法1

代码:

    public ListNode getIntersectionNode(ListNode head1, ListNode head2) {
        if (head1==null||head2==null){
            return null;
        }
        int size1=size(head1);
        int size2=size(head2);
        int size=size1-size2;
        //设长链表为head1,短链表为head2
        if(size<0){
            size=-1*size;
            ListNode tmp=head1;
            head1=head2;
            head2=tmp;
        }
        while(size>0){
            size--;
            head1=head1.next;
        }
        while(head1!=head2){
            head1=head1.next;
            head2=head2.next;
        }
    return head1;
    }
    public int size(ListNode head){
        int count=0;
        while(head!=null){
            count++;
            head=head.next;
        }
        return count;
    }

解析:

(1)

(2) 

 

(3) 

 方法2

代码:

 public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
    if (headA == null || headB == null) return null;
    ListNode pA = headA, pB = headB;
    while (pA != pB) {
        pA = pA == null ? headB : pA.next;
        pB = pB == null ? headA : pB.next;
    }
    return pA;
}

解析:

pA走过的路径为A链+B链

pB走过的路径为B链+A链

pA和pB走过的长度都相同,都是A链和B链的长度之和,相当于将两条链从尾端对齐,如果相交,则会提前在相交点相遇,如果没有相交点,则会在最后相遇。


 3.环形链表

环形链表icon-default.png?t=N7T8https://leetcode.cn/problems/linked-list-cycle/

 

 

代码:

    public boolean hasCycle(ListNode head) {
        if(head==null){
            return false;
        }
            ListNode fast = head;
            ListNode slow = head;
            while(fast != null && fast.next != null) {
                fast = fast.next.next;
                slow = slow.next;
                if(fast == slow) {
                    return true;
                }
            }
            return false;
    }

解析:

【思路】
快慢指针,即慢指针一次走一步,快指针一次走两步,两个指针从链表起始位置开始运行,如果链表 带环则一定会在环中相遇,否则快指针率先走到链表的末尾。

当慢指针刚进环时,可能就和快指针相遇了,最差情况下两个指针之间的距离刚好就是环的长度。此时,两个指针每移动一次,之间的距离就缩小一步,不会出现每次刚好是套圈的情况,因此:在慢指针走到一圈之前,快指针肯定是可以追上慢指 针的,即相遇。

扩展问题 

小结:

走3步,在2个节点的环中实际上是走了一个周期多一步,当走1步的进入环与 走3步的没有相遇,之后就无法相遇,因为速度相同。


 4.环形链表 II

142. 环形链表 IIicon-default.png?t=N7T8https://leetcode.cn/problems/linked-list-cycle-ii/

 

 代码:

    public ListNode detectCycle(ListNode head) {
        if(head==null){
            return null;
        }
        ListNode fast = head;
        ListNode slow = head;
        while(fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
            if(fast == slow) {
                break;
            }
        }
        if(fast == null || fast.next == null){
            return null;
        }
        slow=head;
        while (slow!=fast){
            fast = fast.next;
            slow = slow.next;
        }
        return slow;
    }

解析:

结论
让一个指针从链表起始位置开始遍历链表,同时让一个指针从判环时相遇点的位置开始绕环运行,两个指针 都是每次均走一步,最终肯定会在入口点的位置相遇
证明:


 

以上为我个人的小分享,如有问题,欢迎讨论!!! 

都看到这了,不如关注一下,给个免费的赞 

 

更多推荐

tensorflow基础

windows安装tensorflowanaconda或者pip安装tensorflow,tensorflow只支持win764系统,本人使用tensorflow1.5版本(pipinstalltensorflow==1.5)tensorboardtensorboard只支持chrome浏览器,而且加载过程中可能有一段

革命性创新:RFID技术引领汽车零部件加工新时代

革命性创新:RFID技术引领汽车零部件加工新时代RFID(RadioFrequencyIdentification,射频识别)技术是一种利用无线电频率进行自动识别的技术,可以快速、准确地识别物体并获取相关数据。在汽车零部件加工中,RFID技术可以发挥重要作用,提高生产效率、降低成本和减少错误。本文将介绍RFID在汽车零

激光焊接汽车PP塑料配件透光率测试仪

随着汽车主机厂对车辆轻量化的需求越来越强烈,汽车零部件轻量化设计、制造也成为汽车零部件生产厂商的重要技术指标。零部件企业要实现产品的轻量化,在材料指定的情况下,要通过产品设计优化、产品壁厚减小和装配方式的优化来解决。使用PP材料的汽车部品由于PP材料缩水率高,薄壁化设计会带来后续开发过程产品表面缩水、顶杆痕、应力痕等缺

最新Java JDK 21:全面解析与新特性探讨

🌷🍁博主猫头虎带您GotoNewWorld.✨🍁🦄博客首页——猫头虎的博客🎐🐳《面试题大全专栏》文章图文并茂🦕生动形象🦖简单易学!欢迎大家来踩踩~🌺🌊《IDEA开发秘籍专栏》学会IDEA常用操作,工作效率翻倍~💐🌊《100天精通Golang(基础入门篇)》学会Golang语言,畅玩云原生,走遍大

ChatGPT与日本首相交流核废水事件-精准Prompt...

了解更多请点击:ChatGPT与日本首相交流核废水事件-精准Prompt...https://mp.weixin.qq.com/s?__biz=Mzg2NDY3NjY5NA==&mid=2247490070&idx=1&sn=ebdc608acd419bb3e71ca46acee04890&chksm=ce64e42f

时序数据库 IoTDB 发布端边云原生解决方案,有效优化工业互联网数据上传时效与资源消耗...

2023年9月8日,由中国通信学会、福建省工业和信息化厅主办的2023中国国际工业互联网创新发展大会在厦门举办。大会主论坛中,时序数据库IoTDB发表其自研建立的端边云原生解决方案,该方案可实现端侧设备、边缘服务器、数据中心数据的协同汇聚,达到数据实时上传、带宽成本控制、与多终端同步管理。01关于大会为贯彻落实国家两个

大模型为使用Prompt提供的指导和建议

当使用大型语言模型时,合适的Prompt对于获取理想的响应至关重要。以下是一些常见任务的Prompt示例,以供参考:1.自然语言生成:“请为我生成一篇关于气候变化影响的文章。”“写一封感谢信,内容表达对某位导师的感激之情。”“编写一首诗,描述夏天的美丽。”2.问答任务:“回答以下问题:什么是人工智能?”“解释量子力学的

Java 泛型

目录(generic泛型)引言-idea技巧(快捷键)泛型的理解和好处传统方式用泛型来解决前面的问题(快速入门)泛型的好处泛型基本语法泛型介绍示例代码泛型的声明泛型的实例化(什么时候给泛型指定一个具体的类型)-一般来说是创建一个对象的时候指定的示例代码泛型语法和使用泛型使用案例自定义泛型自定义泛型类自定义泛型接口自定义

Prompt-To-Prompt——仅通过文本进行图像编辑

文章目录1.摘要2.算法2.1Cross-attentionintext-conditionedDiffusionModels2.2ControllingtheCross-attentionWordSwapAddingaNewPhraseAttentionRe–weighting3.应用Text-OnlyLocaliz

【C++】动态内存管理 ④ ( 对象的动态创建和释放引申思考 | 基础数据类型 内存分析 | malloc 分配内存 delete 释放 | new 分配内存 free 释放内存 )

文章目录一、对象的动态创建和释放引申思考二、基础数据类型内存分析1、malloc分配内存delete释放内存2、new分配内存free释放内存一、对象的动态创建和释放引申思考malloc和free是C语言stdlib标准库中的函数,用于分配和回收堆内存;new和delete是C++语言中的操作符,用于分配和回收堆内存;

[C++从入门到精通] 9.inline、const、mutable、this和static

📢博客主页:https://loewen.blog.csdn.net📢欢迎点赞👍收藏⭐留言📝如有错误敬请指正!📢本文由丶布布原创,首发于CSDN,转载注明出处🙉📢现在的付出,都会是一种沉淀,只为让你成为更好的人✨文章预览:一.特殊的成员函数inline二.成员函数末尾的const三.mutable四.返回

热文推荐