“手撕”链表的九道OJ习题

目录

1. 第一题

2. 第二题

3. 第三题

4. 第四题

5. 第五题

6. 第六题

7. 第七题

8. 第八题

9. 第九题


1. 第一题

删除链表中等于给定值 val 的所有节点。OJ链接

思路如下:

相当于链表的removeAll();制定prev和cur,prev记录前一个节点,方便删除。

但是要注意head==null和head.val==val的时候

public ListNode removeElements(ListNode head, int val) {
        if (head == null) {
            return head;
        }
        ListNode cur = head.next;
        ListNode prev = head;
        while (cur != null) {
            if (cur.val == val) {
                prev.next = cur.next;
                cur = cur.next;
            } else {
                prev = cur;
                cur = cur.next;
            }
        }
        if (head.val == val) {
            head = head.next;
        }
        return head;
    }

2. 第二题

反转一个单链表。OJ链接

思路如下:

 头插法,把后面的头插到前面

public ListNode reverseList(ListNode head) {
        if (head == null) {
            return head;
        }
        ListNode cur = head.next;
        head.next = null;
        while (cur != null) {
            ListNode curN = cur.next;
            cur.next = head;
            head = cur;
            cur = curN;
        }
        return head;
    }

3. 第三题

给定一个带有头结点 head 的非空单链表,返回链表的中间结点。如果有两个中间结点,则返回第二个中间结点。OJ链接

思路如下:

快慢指针,快指针走2步,慢指针走1步,当快指针走完,慢指针刚刚好走一半 

public ListNode middleNode(ListNode head) {
        ListNode fast = head;
        ListNode slow = head;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        return slow;
    }

4. 第四题

将两个有序链表合并为一个新的有序链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。OJ链接

思路如下:

定义一个傀儡头节点和tmp,让headA和headB去比较,如果谁小,tmp就跟在谁的后面,然后head小的++,直到一个链表为空 

public ListNode mergeTwoLists(ListNode headA, ListNode headB) {
        ListNode newH = new ListNode(0);
        ListNode tmp = newH;
        while (headA != null && headB != null) {
            if (headA.val < headB.val) {
                tmp.next = headA;
                headA = headA.next;
            } else {
                tmp.next = headB;
                headB = headB.next;
            }
            tmp = tmp.next;
        }
        if (headA == null) {
            tmp.next = headB;
        }
        if (headB == null) {
            tmp.next = headA;
        }
        return newH.next;
    }

5. 第五题

写代码,以给定值x为基准将链表分割成两部分,所有小于x的结点排在大于或等于x的结点之前 。OJ链接

思路如下:

两个链表,一个小链表(头节点as,尾节点ae),一个大链表(头节点bs,尾节点be),小于x放小链表,大于x放大链表。然后让ae指向bs,把两个连接起来

public ListNode partition(ListNode pHead, int x) {
        // write code here
        ListNode as = null;
        ListNode ae = null;
        ListNode bs = null;
        ListNode be = null;
        ListNode cur = pHead;

        while (cur != null) {
            if (cur.val < x) {
                if (as == null) {
                    as = ae = cur;
                } else {
                    ae.next = cur;
                    ae = ae.next;

                }
            } else {
                if (bs == null) {
                    bs = be = cur;
                } else {
                    be.next = cur;
                    be = be.next;
                }
            }
            cur = cur.next;
        }
        if (as == null) {
            return bs;
        }
        ae.next = bs;
        if (bs != null) {
            be.next = null;
        }

        return as;
    }

6. 第六题

链表的回文结构。OJ链接

思路如下:

 用快慢指针找出中间节点,然后把后面的节点进行头插,最后头和尾开始比较val值相不相同

public boolean chkPalindrome(ListNode A) {
        // write code here
        if (A == null) {
            return true;
        }
        ListNode slow = A;
        ListNode fast = A;
        while (fast != null && fast.next != null) {
            fast = fast.next.next;
            slow = slow.next;
        }
        ListNode cur = slow.next;
        while (cur != null) {
            ListNode curN = cur.next;
            cur.next = slow;
            slow = cur;
            cur = curN;
        }
        while (A != slow) {
            if (A.val != slow.val) {
                return false;
            }
            if (A.next == slow) {
                return true;
            }
            A = A.next;
            slow = slow.next;
        }
        return true;
    }

7. 第七题

输入两个链表,找出它们的第一个公共结点。OJ链接

思路如下:
两条链表定义p1和p2,求出每条链表的长度,然后相减,得出多出来的距离,把多出来的距离让长的链表先走。然后两个节点一起走,相遇的点就是公共的第一个节点

public ListNode getIntersectionNode(ListNode headA, ListNode headB) {
        ListNode p1 = headA;
        ListNode p2 = headB;
        int lenA = 0;
        int lenB = 0;
        while (p1 != null) {
            lenA++;
            p1 = p1.next;
        }
        while (p2 != null) {
            lenB++;
            p2 = p2.next;
        }
        int len = lenA - lenB;
        p1 = headA;
        p2 = headB;
        if (len < 0) {
            p1 = headB;
            p2 = headA;
            len = lenB - lenA;
        }
        while (len != 0) {
            p1 = p1.next;
            len--;
        }
        while (p1 != p2) {
            p1 = p1.next;
            p2 = p2.next;
        }
        if (p1 == null) {
            return null;
        }
        return p1;
    }

8. 第八题

给定一个链表,判断链表中是否有环。OJ链接

 思路如下:

快慢指针,快的走两步,慢的走一步。也就是快的先进圈,如果他俩相遇了,就说明有环(假设没环的话,快的先进去,早就空指针null了)

public boolean hasCycle(ListNode head) {
        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;
    }

相遇的原理:

因为fast走得快,slow走得慢。所以fast先进环,slow后进环,我们可以看成fast进了环之后再追slow。我们假设他们距离为N,fast快一步,所以每次都缩短1步,到0之后就相遇了。如下图:

如果fast一次走三步,还能相遇吗?那么他们每走一步追2,如下图:

9. 第九题

给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回 NULL OJ链接

思路如下:

如果快慢指针,快指针走2步,慢指针走1步,她两相遇了,说明有环,这时候我们让快指针重新出发(fast=head),他和慢指针现在以相同的速度前行,当他们再次相遇的时候,就是出口!

public ListNode detectCycle(ListNode head) {
        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;
        }
        fast = head;
        while (fast != slow) {
            fast = fast.next;
            slow = slow.next;
        }
        return fast;
    }
}

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:/a/669279.html

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

2024最新VMware Workstation Pro下载教程

自从2024年5月份之后&#xff0c;VMware workstation player就不能直接在vm官网下载,需要到broadcom博通网站上下载 下面介绍最新下载步骤&#xff1a; 百度直接搜索vmware 进入官网点击Workstation Pro链接 博通注册对应的账号 现在下载都需到博通注册对应的账号 登录邮…

网络原理-TCP/IP --应用层

T04BF &#x1f44b;专栏: 算法|JAVA|MySQL|C语言 &#x1faf5; 今天你敲代码了吗 目录 3.网络原理 -TCP/IP3.1 应用层 3.网络原理 -TCP/IP 3.1 应用层 应用层是程序员打交道最多的一层,与应用程序直接相关 而应用层的协议,实际上就规定了你写的程序,通过网络传输的时候,按…

使用 Scapy 库编写 IP 地址欺骗攻击脚本

一、介绍 1.1 概述 IP地址欺骗&#xff08;IP Spoofing&#xff09;是一种网络攻击技术&#xff0c;攻击者伪造其数据包的源IP地址&#xff0c;使其看起来像是从其他合法地址发送的。这种技术常用于各种攻击中&#xff0c;例如DDoS攻击、Man-in-the-Middle&#xff08;MITM&a…

271 基于matlab的可调Q因子小波变换故障诊断

基于matlab的可调Q因子小波变换故障诊断&#xff0c;可用在轴承、齿轮、活塞等故障诊断中&#xff0c;程序中包含了原始TQWT工具箱和轴承振动信号信号的谱包络的求取。通过仿真数据、实际轴承数据说明了方法的效果。程序已调通&#xff0c;可直接运行。 271 可调Q因子小波变换 …

算法第三天力扣第69题:X的平方根

69. x 的平方根 (可点击下面链接或复制网址进行做题) https://leetcode.cn/problems/sqrtx/https://leetcode.cn/problems/sqrtx/ 给你一个非负整数 x ,计算并返回 x 的 算术平方根 。 由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。 注意:不允许使用任何内…

Gavin Wood 访谈|Polkadot 从何而来,又将如何面对 AI 时代?

如果没有宏观经济&#xff0c;加密世界可能无法存在。或许&#xff0c;Satoshi Nakamoto 也永远不会写出那篇开创性的白皮书。区块链技术作为指数时代的核心之一&#xff0c;在宏观经济理论中占有重要地位。传统的经济增长公式是人口增长加生产率增长加债务增长。然而&#xff…

32【Aseprite 作图】石头——拆解

1 石头先画轮廓&#xff0c;还是2 4 1 1 2 2 2&#xff0c;这样画一个圆的轮廓 或者2 1 1 3 5 1 1 1 1 2 4 &#xff0c; 2 最暗一层的黑色&#xff0c;做阴影部分&#xff0c;就是7 4 3 2 做最深的部分 各个地方画一些浅色的&#xff0c;做高光部分&#xff0c;上面的高光偏圆…

依赖管理包介绍

文章目录 1. 概念介绍2. 思路与方法2.1 实现思路2.2 相关组件 3. 示例代码4. 内容总结 我们在上一章回中介绍了"使用get进行依赖管理"相关的内容&#xff0c;本章回中将介绍如何使用get进行状态管理一.闲话休提&#xff0c;让我们一起Talk Flutter吧。 1. 概念介绍 …

【计算机毕设】SpringBoot海滨体育馆管理系统设计与实现 - 源码免费(私信领取)

免费领取源码 &#xff5c; 项目完整可运行 &#xff5c; v&#xff1a;chengn7890 诚招源码校园代理&#xff01; 1. 引言 体育馆作为重要的体育场馆&#xff0c;承担着举办体育赛事、健身活动和文化演出等多种功能。为了提高体育馆的管理效率和服务质量&#xff0c;本项目旨在…

2024-05-31 blue-VH-driver-问题分析-有状态的服务-状态的处理

摘要: VH的driver对上层提供的接口&#xff0c;是会保持状态。这个状态&#xff0c;可以分为&#xff0c;查询的数据的状态&#xff0c;主要是为了提供翻页查询的功能。另一种状态&#xff0c;就是订阅。 有状态的服务: 状态是什么? 其实从调用方的角度更好的理解&#xff0c…

进程与线程(三)

进程与线程&#xff08;三&#xff09; 进程间通信传统间的进程间通信机制无名管道无名管道的特征无名管道的创建父子进程通信测试管道的大小管道读写易出现的问题 有名管道创建有名管道有名管道的写端代码有名管道的读端代码 信号信号的特征产生信号硬件来源软件来源发送信号的…

【MATLAB】概述1

非 ~ 注释 % 定义 >> 数组 赋值 赋值&#xff1a;>> x1 函数 数组 x[x1,x2] 行向量&#xff08;&#xff0c;or ) x[x1;x2] 列向量 x. 转置等间隔向量 1-10 向量&#xff1a;>>xlinspace(1,10,10) 矩阵 矩阵&#xff1a;>>A[1,2,3;4,5,6;7,8,9] …

重生之 SpringBoot3 入门保姆级学习(10、日志基础与使用)

重生之 SpringBoot3 入门保姆级学习&#xff08;10、日志基础使用&#xff09; 3.1 日志基础3.2 使用日志3.2.1 基础使用3.2.2 调整日志级别3.2.3 带参数的日志 3.1 日志基础 SpringBoot 默认使用 SLF4j&#xff08;Simple Logging Facade for Java&#xff09;和 Logback 实现…

Django ORM魔法:用Python代码召唤数据库之灵!

探索Django ORM的神奇世界&#xff0c;学习如何用Python代码代替复杂的SQL语句&#xff0c;召唤数据库之灵&#xff0c;让数据管理变得轻松又有趣。从基础概念到高级技巧&#xff0c;阿佑带你一步步成为Django ORM的魔法师&#xff0c;让你的应用开发速度飞起来&#xff01; 文…

Adobe Acrobat DC无法卸载

控制版面、电脑管家等均无法卸载&#xff0c;使用自身的remove也不能卸载 解决方法&#xff1a;删除Adobe Acrobat DC的注册表 1、首先打开注册列表&#xff1a; 2、根据圈出来的信息&#xff0c;找到以下路径&#xff1a; 计算机\HKEY_LOCAL_MACHINE\SOFTWARE\Classes\Inst…

c++车票管理系统

这里写自定义目录标题 c车票管理系统vx:sredxc车票管理系统初始页面,需要源码vx:sredxc新增车票信息查询车票信息代码包含完整的发布车票信息,购票,退票,票数检测,余票检测,车票查询等功能 c车票管理系统vx:sredxc 这段代码实现了一个简单的高铁票务管理系统&#xff0c;具有以…

动态路由OSPF单区域和多区域配置实验

动态路由OSPF的配置 OSPF分类两种情况&#xff1a;单区域 多区域路由 OSPF单区域路由配置 OSPF&#xff1a;开放最短路径优先的路由协议。属于大型动态路由协议&#xff0c;适用于中大型的园区网。 网络拓扑&#xff1a; 配置步骤&#xff1a; 1.完成基本配置&#xff08;略&…

如何在测试/线上环境页面访问本地接口?

文章目录 一、前言二、分析三、搭建1、搭建nginx&#xff0c;监听http请求转发2、监听https请求转发 四、总结 一、前言 在工作中&#xff0c;开发完的接口&#xff0c;一般测试的话&#xff0c;基本是使用Postman&#xff0c;如果要到页面测试&#xff0c;就要发版进行测试&a…

5.29工效学-人因工程人机交互

对于工效学这门课&#xff0c;一直都感觉很有意思&#xff0c;是一个值得再认真一点的课。可惜上课的时候效率不高&#xff0c;有感兴趣的东西课后也没有自行去拓展开来&#xff0c;前面的课我感觉还讲了比较重要的东西&#xff0c;但是&#xff0c;全忘了呢&#xff08;真的对…

8、资源操作 Resource

目录 8.1、Spring Resources概述补充&#xff1a;什么是 low-level 资源&#xff1f;1. 文件系统资源2. 类路径资源3. URL资源4. 内嵌资源5. InputStream资源6. ServletContext资源示例代码结论 8.2、Resource接口8.3、Resource的实现类8.3.1、UrlResource访问网络资源1&#x…