【链表】算法例题

 

目录

 八、 链表

57. 环形链表 ① ×

58. 两数相加 ② √

59. 合并两个有序链表 ① √-

60. 随机链表的复制 ②

61. 反转链表II ② ×

62. K个一组翻转链表 ③

63. 删除链表的倒数第N个结点 ② √-

64. 删除排序链表中的重复元素II ②  √-

65. 旋转链表 ② √-

66. 分隔链表 ② √

67. LRU缓存 ②


八、 链表

57. 环形链表 ① ×

给你一个链表的头节点 head ,判断链表中是否有环。

如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。

如果链表中存在环 ,则返回 true 。 否则,返回 false 。

示例 1:

输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。

示例 2:

输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。

示例 3:

输入:head = [1], pos = -1
输出:false
解释:链表中没有环。

提示:

  • 链表中节点的数目范围是 [0, 104]
  • -105 <= Node.val <= 105
  • pos 为 -1 或者链表中的一个 有效索引 。

进阶:你能用 O(1)(即,常量)内存解决此问题吗?

力扣解析:

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

方法2:(0ms)

    public boolean hasCycle(ListNode head) {if (head == null || head.next == null) return false;int n = 10010;while (n -- > 0) {head = head.next;if (head == null) return false;}return true;}

58. 两数相加 ② √

给你两个 非空 的链表,表示两个非负的整数。它们每位数字都是按照 逆序 的方式存储的,并且每个节点只能存储 一位 数字。

请你将两个数相加,并以相同形式返回一个表示和的链表。

你可以假设除了数字 0 之外,这两个数都不会以 0 开头。

示例 1:

输入:l1 = [2,4,3], l2 = [5,6,4]
输出:[7,0,8]
解释:342 + 465 = 807.

示例 2:

输入:l1 = [0], l2 = [0]
输出:[0]

示例 3:

输入:l1 = [9,9,9,9,9,9,9], l2 = [9,9,9,9]
输出:[8,9,9,9,0,0,0,1]

提示:

  • 每个链表中的节点数在范围 [1, 100] 内
  • 0 <= Node.val <= 9
  • 题目数据保证列表表示的数字不含前导零

方法1:(1ms)

    public ListNode addTwoNumbers(ListNode l1, ListNode l2) {ListNode head = new ListNode();ListNode temp = head;int more = 0;int res = 0;while (!(l1 == null && l2 == null)){res = (l1 != null? l1.val : 0) + (l2 != null? l2.val : 0) + more;if (res > 9){res = res - 10;more = 1;}else {more = 0;}ListNode newNode = new ListNode(res);temp.next = newNode;temp = temp.next;if (l1.next != null){l1 = l1.next;}if (l2.next != null){l2 = l2.next;}}if (more == 1){temp.next = new ListNode(more);}return head.next;}

59. 合并两个有序链表 ① √-

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

示例 1:

输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]

示例 2:

输入:l1 = [], l2 = []
输出:[]

示例 3:

输入:l1 = [], l2 = [0]
输出:[0]

提示:

  • 两个链表的节点数目范围是 [0, 50]
  • -100 <= Node.val <= 100
  • l1 和 l2 均按 非递减顺序 排列

方法1:(0ms)

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {if (list1 == null && list2 == null) {return null;} else if (list1 == null && list2 != null) {return list2;} else if (list1 != null && list2 == null) {return list1;}ListNode head = new ListNode();ListNode left = list1;ListNode right = list2;ListNode temp = head;while (left != null && right != null) {if (left.val < right.val) {temp.next = left;left = left.next;} else {temp.next = right;right = right.next;}temp = temp.next;}if (left == null) {temp.next = right;} else if (right == null) {temp.next = left;}return head.next;}

方法2:(0ms  递归)

    public ListNode mergeTwoLists(ListNode list1, ListNode list2) {if (list1 == null) {return list2;}else if (list2 == null) {return list1;}else if (list1.val < list2.val) {list1.next = mergeTwoLists(list1.next, list2);return list1;}else {list2.next = mergeTwoLists(list1, list2.next);return list2;}}

60. 随机链表的复制 ②

61. 反转链表II ② ×

给你单链表的头指针 head 和两个整数 left 和 right ,其中 left <= right 。请你反转从位置 left 到位置 right 的链表节点,返回 反转后的链表 。

示例 1:

输入:head = [1,2,3,4,5], left = 2, right = 4
输出:[1,4,3,2,5]

示例 2:

输入:head = [5], left = 1, right = 1
输出:[5]

提示:

  • 链表中节点数目为 n
  • 1 <= n <= 500
  • -500 <= Node.val <= 500
  • 1 <= left <= right <= n

力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

方法2:(0ms)

    public ListNode reverseBetween(ListNode head, int m, int n) {// 定义一个dummyHead, 方便处理ListNode dummyHead = new ListNode(0);dummyHead.next = head;// 初始化指针ListNode g = dummyHead;ListNode p = dummyHead.next;// 将指针移到相应的位置for(int step = 0; step < m - 1; step++) {g = g.next; p = p.next;}// 头插法插入节点for (int i = 0; i < n - m; i++) {ListNode removed = p.next;p.next = p.next.next;removed.next = g.next;g.next = removed;}return dummyHead.next;}作者:贾卷积
链接:https://leetcode.cn/problems/reverse-linked-list-ii/solutions/138910/java-shuang-zhi-zhen-tou-cha-fa-by-mu-yi-cheng-zho/

62. K个一组翻转链表 ③

63. 删除链表的倒数第N个结点 ② √-

给你一个链表,删除链表的倒数第 n 个结点,并且返回链表的头结点。

示例 1:

输入:head = [1,2,3,4,5], n = 2
输出:[1,2,3,5]

示例 2:

输入:head = [1], n = 1
输出:[]

示例 3:

输入:head = [1,2], n = 1
输出:[1]

提示:

  • 链表中结点的数目为 sz
  • 1 <= sz <= 30
  • 0 <= Node.val <= 100
  • 1 <= n <= sz

进阶:你能尝试使用一趟扫描实现吗?

方法1:(0ms)

    public ListNode removeNthFromEnd(ListNode head, int n) {if (head.next == null && n == 1){return null;}int count = 1;ListNode temp = head;while (temp.next != null){count++;temp = temp.next;}if (n == count){return head.next;}else {int cnt = 1;temp = head;while (cnt < count - n) {cnt++;temp = temp.next;}temp.next = temp.next.next;return head;}}

 方法2:(0ms)

解题思路:
整体思路是让前面的指针先移动 n 步,之后前后指针共同移动直到前面的指针到尾部为止
首先设立预先指针 pre
设预先指针 pre 的下一个节点指向 head,设前指针为 start,后指针为 end,二者都等于 pre
start 先向前移动n步
之后 start 和 end 共同向前移动,此时二者的距离为 n,当 start 到尾部时,end 的位置恰好为倒数第 n 个节点
因为要删除该节点,所以要移动到该节点的前一个才能删除,所以循环结束条件为 start.next != null
删除后返回 pre.next,为什么不直接返回 head 呢,因为 head 有可能是被删掉的点
时间复杂度:O(n)

作者:画手大鹏
链接:https://leetcode.cn/problems/remove-nth-node-from-end-of-list/solutions/7803/hua-jie-suan-fa-19-shan-chu-lian-biao-de-dao-shu-d/
 

    //通过快慢指针来解决,类似于你要删除中间元素的题public ListNode removeNthFromEnd(ListNode head, int n) {//定义一个伪节点,用于返回结果ListNode dumpy = new ListNode(0);dumpy.next = head;//定义一个快指针,指向伪节点,用于遍历链表ListNode prev = dumpy;//定一个慢指针,ListNode tail = dumpy;//让快指针先移动 n 步while(n >0){prev = prev.next;n--;}//只要快指针不指向空,就继续循环while(prev.next !=null){//让快慢指针同时移动tail = tail.next;prev = prev.next;}//这时慢指针移动到的位置就是,要删除节点的前一个节点//所以只要删除当前节点的下一个节点tail.next = tail.next.next;//返回为指针指向的头节点return dumpy.next;}

64. 删除排序链表中的重复元素II ②  √-

给定一个已排序的链表的头 head , 删除原始链表中所有重复数字的节点,只留下不同的数字 。返回 已排序的链表 。

示例 1:

输入:head = [1,2,3,3,4,4,5]
输出:[1,2,5]

示例 2:

输入:head = [1,1,1,2,3]
输出:[2,3]

提示:

  • 链表中节点数目在范围 [0, 300] 内
  • -100 <= Node.val <= 100
  • 题目数据保证链表已经按升序 排列

方法1:(0ms)

    public static ListNode deleteDuplicates(ListNode head) {if (head == null || head.next == null){return head;}ListNode pre = new ListNode(0);pre.next = head;ListNode newNode = pre;while (head != null && head.next != null){if (head.val != head.next.val) {   // 用值做比较,而不是两个节点做比较,节点一定不相等head = head.next;pre = pre.next;}else {while (head.next != null && head.next.val == head.val){  // 用值做比较head = head.next;}head = head.next;pre.next = head;}}return newNode.next;}

解题思路:力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

65. 旋转链表 ② √-

给你一个链表的头节点 head ,旋转链表,将链表每个节点向右移动 k 个位置。

示例 1:

输入:head = [1,2,3,4,5], k = 2
输出:[4,5,1,2,3]

示例 2:

输入:head = [0,1,2], k = 4
输出:[2,0,1]

提示:

  • 链表中节点的数目在范围 [0, 500] 内
  • -100 <= Node.val <= 100
  • 0 <= k <= 2 * 109

方法1:(1842ms)

    public static ListNode rotateRight(ListNode head, int k) {if (head == null || head.next == null || k == 0){return head;}ListNode temp = head;ListNode pre = new ListNode(0);pre.next = head;int cnt = 0;while (cnt < k - 1){if (temp.next == null){temp = head;}else {temp = temp.next;}cnt++;}while (temp != null){pre = pre.next;temp = temp.next;}ListNode cur = pre;while (pre.next != null){pre = pre.next;}while (head != cur){pre.next = new ListNode(head.val);pre = pre.next;head = head.next;}return cur;}

方法2:(0ms)

    public static ListNode rotateRight(ListNode head, int k) {if(head == null || head.next == null || k <= 0) {return head;}int n = 0;ListNode p = head;while(p != null) {p = p.next;n++;}k = k%n;if(k == n || k == 0) {return head;}ListNode slow = head , fast = head;for(int i=0; i<n-1; i++) {if(i >= k) {slow = slow.next;}fast = fast.next;}ListNode ans = head;ans = slow.next; //slow为新链表头结点的前一个节点 slow.next = null; //在旧链表中将新链表头结点与之前的节点斩断fast.next = head;  //旧链表的尾节点连接上旧链表的头结点return ans;}

66. 分隔链表 ② √

给你一个链表的头节点 head 和一个特定值 x ,请你对链表进行分隔,使得所有 小于 x 的节点都出现在 大于或等于 x 的节点之前。

你应当 保留 两个分区中每个节点的初始相对位置。

示例 1:

输入:head = [1,4,3,2,5,2], x = 3
输出:[1,2,2,4,3,5]

示例 2:

输入:head = [2,1], x = 2
输出:[1,2]

提示:

  • 链表中节点的数目在范围 [0, 200] 内
  • -100 <= Node.val <= 100
  • -200 <= x <= 200

方法1:(0ms)

    public static ListNode partition(ListNode head, int x) {if (head == null || head.next == null){return head;}ListNode pre = new ListNode(0);pre.next = head;ListNode temp = head;ListNode newList = pre;while (temp != null && temp.val < x){temp = temp.next;pre = pre.next;}if (temp == null){return head;}ListNode cur = temp;ListNode newPre = new ListNode(0);newPre.next = temp;ListNode newCur = cur;while (cur != null){if (cur.val < x){newCur = cur.next;pre.next = new ListNode(cur.val);pre = pre.next;cur = newCur;newPre.next = cur;}else {cur = cur.next;newPre = newPre.next;}}pre.next = temp;return newList.next;}

方法2:(0ms):力扣(LeetCode)官网 - 全球极客挚爱的技术成长平台

    public ListNode partition(ListNode head, int x) {ListNode smlDummy = new ListNode(0), bigDummy = new ListNode(0);ListNode sml = smlDummy, big = bigDummy;while (head != null) {if (head.val < x) {sml.next = head;sml = sml.next;} else {big.next = head;big = big.next;}head = head.next;}sml.next = bigDummy.next;big.next = null;return smlDummy.next;}作者:Krahets
链接:https://leetcode.cn/problems/partition-list/solutions/2362068/86-fen-ge-lian-biao-shuang-zhi-zhen-qing-hha7/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

67. LRU缓存 ②

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

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

安科瑞精密配电柜助力数据中心节能降耗

彭姝麟 Acrelpsl 1.趋势分析 能源支出作为数据中心运营的主要成本之一。清华大学能源互联网创新研究院常务副院长高文胜曾在公开场合指出&#xff0c;随着我国数据中心能源消耗的逐年攀升&#xff0c;电费支出约占数据中心年运营成本的95%。加之“双碳”战略的出台&#xff0c…

SkyWalking上报Java应用数据

重要 本文中含有需要您注意的重要提示信息&#xff0c;忽略该信息可能对您的业务造成影响&#xff0c;请务必仔细阅读。 通过SkyWalking为应用埋点并上报链路数据至可观测链路 OpenTelemetry 版后&#xff0c;可观测链路 OpenTelemetry 版即可开始监控应用&#xff0c;您可以…

cyclictest 交叉编译报错---rt_numa.h:18:10: fatal error: numa.h: 没有那个文件或目录

cyclictest 主要是用于测试系统延时&#xff0c;进而判断系统的实时性 使用版本 rt-tests-2.6.tar.gz numactl v2.0.16 问题 编译时&#xff0c;需要先编译 numactl &#xff0c;不然会有以下报错&#xff1a; arm-linux-gnueabihf-gcc -D VERSION2.6 -c src/cyclictest/c…

软考 网工 每日学习打卡 2024/3/19

学习内容 第8章 网络安全 本章主要讲解网络安全方面的基础知识和应用技术。针对考试应该掌握诸如数据加密、报文认 证、数字签名等基本理论&#xff0c;在此基础上深入理解网络安全协议的工作原理&#xff0c;并能够针对具体的 网络系统设计和实现简单的安全解决方案。 本章共有…

Day22初识集合

Day22初识集合 一、集合 1、概念&#xff1a; 集合是指将多个元素组合在一起的数据结构。在编程中&#xff0c;集合用于存储和操作一组相关的数据对象。与数组相比&#xff0c;集合具有更灵活、动态和高级的功能。 2、常见的集合类&#xff1a; List&#xff08;列表&#x…

sentry-cli - error: Failed to load .sentryclirc file from project path

Xcode 15.2 warning sentry-cli - error: Failed to load .sentryclirc file from project path (/Users/zhuhongwei/Desktop/pandabill/.sentryclirc)推荐一下刚上线的 App 熊猫小账本&#xff0c;里面有用到这篇博客讲的内容 熊猫小账本 一个简洁的记账 App&#xff0c;用于…

1、鸿蒙学习-为应用/服务进行签名

针对应用/服务的签名&#xff0c;DevEco Studio为开发者提供了自动签名方案&#xff0c;帮助开发者高效进行调试。也可选择手动方式对应用/服务进行签名&#xff0c;如果使用了需要ACL的权限&#xff0c;需采用手动方式进行签名。 自动签名 说明 使用自动签名前&#xff0c;请…

闭包机制的底层实现原理

说明:此次分享不涉及ES6的let,const,块级作用域,这些其实都是对本次分享内容的扩展。 闭包的重要性 JS的内功心法,闭包是JavaScript中非常重要的核心概念,关系着JS里很多核心的机制,理解了它,很多问题都会迎刃而解,不理解闭包用JS永远像隔着一层窗户纸。 前端发展日新…

【MySQL】学习和总结使用列子查询查询员工工资信息

&#x1f308;个人主页: Aileen_0v0 &#x1f525;热门专栏: 华为鸿蒙系统学习|计算机网络|数据结构与算法 ​&#x1f4ab;个人格言:“没有罗马,那就自己创造罗马~” #mermaid-svg-5odctDvQ0AHJJc1C {font-family:"trebuchet ms",verdana,arial,sans-serif;font-siz…

中国(京津冀)太阳能光伏推进大会暨展览会

中国(京津冀)太阳能光伏推进大会暨展览会是一个旨在促进太阳能光伏产业的发展的重要活动。该活动旨在加大对太阳能光伏的投资和支持&#xff0c;推动太阳能光伏技术的创新和应用&#xff0c;促进太阳能光伏产业的规模化发展。 此次大会暨展览会将为太阳能光伏行业相关企业提供一…

【Linux】Linux基本开发工具(yum) (vi/vim)的使用

本文章内容&#xff1a; 学习yum工具&#xff0c;进行软件安装掌握vim编辑器使用 Linux 软件包管理器 yum 什么是软件包 在Linux下安装软件, 一个通常的办法是下载到程序的源代码, 并进行编译, 得到可执行程序.但是这样太麻烦了, 于是有些人把一些常用的软件提前编译好, 做成…

es 聚合操作(一)

前言 Elasticsearch除搜索以外&#xff0c;提供了针对ES 数据进行统计分析的功能。聚合(aggregations)可以让我们极其方便的实现对数据的统计、分析、运算。例如&#xff1a; 衣服品牌的受欢迎程度这些衣服的平均价格、最高价格、最低价格这些衣服的每天、每月销量如何 使用…

产品推荐 | 基于Xilinx Zynq UltraScale+打造的仙女座 Andromeda FPGA核心板

1、产品概述 仙女座Andromeda XZU65片上系统&#xff08;SoC&#xff09;核心板通过结合高端Xilinx Zynq UltraScale™ MPSoC系列芯片和高速DDR4 ECC SDRAM、eMMC flash、双QSPI flash、双Gigabit Ethernet PHY、USB 3.0形成了一个完整的、功能强大的嵌入式处理系统。得益于大…

Rhino与Revit API之间的转换

你好&#xff0c;我是九哥~ 最近发现Rhino.Inside.Revit的API手册更新了&#xff0c;终于可以开心的写RIR代码了&#xff0c;小伙伴快去试试吧&#xff0c;地址如下&#xff1a; https://www.rhino3d.com/inside/revit/1.0/reference/rir-api 今天我们先来聊聊 Rhino 与 Rev…

华为ensp中rip动态路由协议原理及配置命令(详解)

CSDN 成就一亿技术人&#xff01; 作者主页&#xff1a;点击&#xff01; ENSP专栏&#xff1a;点击&#xff01; CSDN 成就一亿技术人&#xff01; ————前言————— RIP&#xff08;Routing Information Protocol&#xff0c;路由信息协议&#xff09;是一种距离矢…

xss.pwnfunction(DOM型XSS)靶场

环境进入该网站 Challenges (pwnfunction.com) 第一关&#xff1a;Ma Spaghet! 源码&#xff1a; <!-- Challenge --> <h2 id"spaghet"></h2> <script>spaghet.innerHTML (new URL(location).searchParams.get(somebody) || "Somebo…

YOLO_you only look once

前言 计算机图形学的课程即将结束&#xff0c;我需要提交一份关于YOLO模型的学习报告。在这段时间里&#xff0c;我对YOLO进行了深入的学习和研究&#xff0c;并记录下了我的学习过程和心得体会。本文将详细介绍YOLO模型的原理、优缺点以及应用领域&#xff0c;希望能够为后续…

css 如何获取分辨率(使用@media查询)

在CSS中&#xff0c;可以使用media查询来应对不同的屏幕分辨率。例如&#xff0c;您可以为不同的屏幕宽度设置不同的样式规则。 /* 针对屏幕宽度小于600px的样式 */ media screen and (max-width: 599px) {body {background-color: lightblue;} }/* 针对屏幕宽度大于或等于600…

spring整合Sentinel

安装sentinel&#xff1a; 执行命令; java -jar sentinel-dashboard-1.8.6.jar 注:sentinel的默认端口为8080&#xff0c;容易出现tomcat的冲突。 当端口冲突&#xff0c;可以使用该指令修改sentinel的端口 默认账号和密码都为sentinel Springcloud整合sentinel&#xff1a;…