【链表】算法例题

 

目录

 八、 链表

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,一经查实,立即删除!

相关文章

MySQL 数据库的备份和还原

1.命令行 备份语法 mysqldump -u用户名 -p密码 数据库名称 > 保存的路径还原语法 1.登陆数据库 2.创建数据库 3.使用数据库 4.执行文件 source 文件路径2.图形化(太简单了不写了) 点击返回 MySQL 快速学习目录

全球首位AI程序员诞生,将会对程序员的影响有多大?

近期&#xff0c;全球首位AI程序员Devin的出场&#xff0c;不禁让我想到了一个有趣的问题&#xff1a;AI程序员会不会抢程序员的饭碗呢&#xff1f;先别着急下结论&#xff01;虽然AI技术在编程领域越来越广泛&#xff0c;但它真的能完全替代我们程序员吗&#xff1f; 方向一&…

【中级软件设计师】上午题07-面向对象技术(通俗易懂版)

上午题07-面向对象技术 1 类2 对象和消息2.1 对象2.2 消息 3 方法重载4 封装5 继承6 多态7 静态、动态绑定8 面向对象设计原则9 面向对象分析与设计9.1 面向对象分析9.2 面向对象设计9.3 面向对象测试 1 类 实体、接口、控制 类是在对象之上的抽象&#xff0c;对象是类的具体…

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

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

markdown支持的emoji表情

markdown-emoji Markdown语法支持添加 emoji 表情&#xff0c;输入不同的符号码&#xff08;两个冒号包围的字符&#xff09;可以显示出不同的表情 Emoji Cheat Sheet全列表参见&#xff1a;Emoji Cheat Sheet markdown-emoji 人物自然事物地点符号 人物 :bowtie: :bowtie…

ActiViz三维场景的基本要素——灯光

文章目录 一、ActiViz 中灯光的基本要素二、ActiViz 中灯光的使用方法三、ActiViz 中灯光的高级特性四、性能优化和注意事项五、总结一、ActiViz 中灯光的基本要素 灯光是在三维场景中模拟光照效果的重要组成部分。在 ActiViz 中,灯光具有多种类型和属性,可以通过设置这些属…

字符串(string)篇(一)

文章目录 1.1 capitalize()函数1.2 casefold()函数1.3 center()函数1.4 count()函数1.5 decode()函数1.6 encode()函数1.7 endswith()函数1.8 expandtabs()函数1.9 find()函数 1.1 capitalize()函数 在Python中&#xff0c;capitalize() 是一个字符串&#xff08;string&#…

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;并能够针对具体的 网络系统设计和实现简单的安全解决方案。 本章共有…

量化交易入门(七)Python开发-面向对象和类

在Python中,面向对象(OO)是一种编程范式或思想,它将现实世界中的实体抽象为对象(Object),通过对象之间的交互来解决问题&#xff0c;在量化交易中&#xff0c;它可以帮助我们更好地组织和管理复杂的交易策略和系统。在面向对象编程中,我们把数据和操作数据的方法封装在对象内部…

Day22初识集合

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

454.四数相加

给你四个整数数组 nums1、nums2、nums3 和 nums4 &#xff0c;数组长度都是 n &#xff0c;请你计算有多少个元组 (i, j, k, l) 能满足&#xff1a; 0 < i, j, k, l < nnums1[i] nums2[j] nums3[k] nums4[l] 0 方法一&#xff1a; 双层for循环&#xff0c;将nums1、…

KY115 后缀字串排序

描述&#xff1a; 对于一个字符串&#xff0c;将其后缀子串进行排序&#xff0c;例如grain 其子串有&#xff1a; grain rain ain in n 然后对各子串按字典顺序排序&#xff0c;即&#xff1a; ain,grain,in,n,rain 输入描述&#xff1a; 每个案例为一行字符串。 输出描述&…

JS的Document属性和方法

在javascript中&#xff0c;document对象是一个非常重要的全局对象&#xff0c;它代表整个html文档。你可以通过document对象来访问和修改html文档的内容和结构。以下是一些常见的document属性和方法&#xff1a; 属性 1、document.title&#xff1a;获取或设置文档的标题&am…

HTML 特殊元素:展示PDF、展示JSON 数据

<pre> 标签 (preformatted text) <pre> 标签用来表示预格式化的文本内容 在页面数据展示时&#xff0c;后端返回了一段未经处理的JSON 数据&#xff0c;将这段数据在页面正常展示&#xff0c;让可读性更高。 {/"project": {/ "title": "…

TSP问题消除子环

个人感觉看这一个就够了&#xff01;&#xff01;&#xff01; 优化│TSP中两种不同消除子环路的方法及callback实现&#xff08;Python调用Gurobi求解&#xff09; 刘兴禄运筹学修炼日记&#xff1a;TSP中两种不同消除子环路的方法及callback实现&#xff08;Python调用Guro…

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;请…