首页 > 编程语言 >代码随想录算法训练营第四天 |24. 两两交换链表中的节点 | 19.删除链表的倒数第N个节点 | 面试题 02.07. 链表相交 | 142.环形链表II

代码随想录算法训练营第四天 |24. 两两交换链表中的节点 | 19.删除链表的倒数第N个节点 | 面试题 02.07. 链表相交 | 142.环形链表II

时间:2024-02-01 14:24:59浏览次数:31  
标签:head 随想录 fast Next 链表 节点 指针

142. 环形链表 II

  已解答 中等  

相关标签

相关企业  

给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null

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

不允许修改 链表。

 

示例 1:

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

示例 2:

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

示例 3:

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

 

提示:

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

 

进阶:你是否可以使用 O(1) 空间解决此题?


  1. 判断有没有环, 用快慢指针, 快走2, 慢走1, 快相对与慢走1, 所以有环就一定能遇到
  2. 判断入环点的逻辑,数字逻辑参推到, z=x%(z+y) 再找到相遇点 m 时, 再新增个head点,同时并进
  3. 当他们相遇时那个就是入环点, 没有想到

此时已经可以判断链表是否有环了,那么接下来要找这个环的入口了。

假设从头结点到环形入口节点 的节点数为x。 环形入口节点到 fast指针与slow指针相遇节点 节点数为y。 从相遇节点 再到环形入口节点节点数为 z。 如图所示:

那么相遇时: slow指针走过的节点数为: x + y, fast指针走过的节点数:x + y + n (y + z),n为fast指针在环内走了n圈才遇到slow指针, (y+z)为 一圈内节点的个数A。

因为fast指针是一步走两个节点,slow指针一步走一个节点, 所以 fast指针走过的节点数 = slow指针走过的节点数 * 2:

(x + y) * 2 = x + y + n (y + z)

两边消掉一个(x+y): x + y = n (y + z)

因为要找环形的入口,那么要求的是x,因为x表示 头结点到 环形入口节点的的距离。

所以要求x ,将x单独放在左面:x = n (y + z) - y ,

再从n(y+z)中提出一个 (y+z)来,整理公式之后为如下公式:x = (n - 1) (y + z) + z 注意这里n一定是大于等于1的,因为 fast指针至少要多走一圈才能相遇slow指针。

这个公式说明什么呢?

先拿n为1的情况来举例,意味着fast指针在环形里转了一圈之后,就遇到了 slow指针了。

当 n为1的时候,公式就化解为 x = z

这就意味着,从头结点出发一个指针,从相遇节点 也出发一个指针,这两个指针每次只走一个节点, 那么当这两个指针相遇的时候就是 环形入口的节点

也就是在相遇节点处,定义一个指针index1,在头结点处定一个指针index2。

让index1和index2同时移动,每次移动一个节点, 那么他们相遇的地方就是 环形入口的节点。

 

      func detectCycle(head *ListNode) *ListNode { fast, slow := head, head //先确定是否有环(fast与slow能相遇) for fast != nil && fast.Next != nil { fast = fast.Next.Next slow = slow.Next if fast != slow { continue } //由相遇到,到开始点同步进步,相遇就是环起点,这点逻辑不好理解 meetNode := fast startNode := head for meetNode != startNode { meetNode = meetNode.Next startNode = startNode.Next } return startNode } return nil }

 

面试题 02.07. 链表相交

  已解答 简单  

相关标签

相关企业  

提示

 

给你两个单链表的头节点 headA 和 headB ,请你找出并返回两个单链表相交的起始节点。如果两个链表没有交点,返回 null 。

图示两个链表在节点 c1 开始相交

题目数据 保证 整个链式结构中不存在环。

注意,函数返回结果后,链表必须 保持其原始结构 。

 

示例 1:

输入:intersectVal = 8, listA = [4,1,8,4,5], listB = [5,0,1,8,4,5], skipA = 2, skipB = 3
输出:Intersected at '8'
解释:相交节点的值为 8 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [4,1,8,4,5],链表 B 为 [5,0,1,8,4,5]。
在 A 中,相交节点前有 2 个节点;在 B 中,相交节点前有 3 个节点。

示例 2:

输入:intersectVal = 2, listA = [0,9,1,2,4], listB = [3,2,4], skipA = 3, skipB = 1
输出:Intersected at '2'
解释:相交节点的值为 2 (注意,如果两个链表相交则不能为 0)。
从各自的表头开始算起,链表 A 为 [0,9,1,2,4],链表 B 为 [3,2,4]。
在 A 中,相交节点前有 3 个节点;在 B 中,相交节点前有 1 个节点。

示例 3:

输入:intersectVal = 0, listA = [2,6,4], listB = [1,5], skipA = 3, skipB = 2
输出:null
解释:从各自的表头开始算起,链表 A 为 [2,6,4],链表 B 为 [1,5]。
由于这两个链表不相交,所以 intersectVal 必须为 0,而 skipA 和 skipB 可以是任意值。
这两个链表不相交,因此返回 null 。

 

提示:

  • listA 中节点数目为 m
  • listB 中节点数目为 n
  • 0 <= m, n <= 3 * 104
  • 1 <= Node.val <= 105
  • 0 <= skipA <= m
  • 0 <= skipB <= n
  • 如果 listA 和 listB 没有交点,intersectVal 为 0
  • 如果 listA 和 listB 有交点,intersectVal == listA[skipA + 1] == listB[skipB + 1]

 

进阶:你能否设计一个时间复杂度 O(n) 、仅用 O(1) 内存的解决方案?


func getIntersectionNode(headA, headB *ListNode) *ListNode { var countA, countB int nodeA, nodeB := headA, headB for nodeA != nil { nodeA = nodeA.Next countA++ } for nodeB != nil { nodeB = nodeB.Next countB++ } if countA < countB { headB, headA = headA, headB countA, countB = countB, countA } for i := 0; i < countA-countB; i++ { headA = headA.Next } for headA != nil { if headA == headB { return headA } headA = headA.Next headB = headB.Next } return nil }

 

19. 删除链表的倒数第 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

 

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


func removeNthFromEnd(head *ListNode, n int) *ListNode { dummy := &ListNode{Next: head} slow, fast := dummy, dummy for i := 0; i < n; i++ { fast = fast.Next } for fast.Next != nil { slow = slow.Next fast = fast.Next } slow.Next = slow.Next.Next return dummy.Next }  

 

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

  已解答 中等  

相关标签

相关企业  

给你一个链表,两两交换其中相邻的节点,并返回交换后链表的头节点。你必须在不修改节点内部的值的情况下完成本题(即,只能进行节点交换)。

 

示例 1:

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

示例 2:

输入:head = []
输出:[]

示例 3:

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

 

提示:

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

func swapPairs(head *ListNode) *ListNode { dummy := &ListNode{Next: head} node := dummy for node.Next != nil && node.Next.Next != nil { a := node.Next b := a.Next node.Next = b a.Next = b.Next b.Next = a node = a } return dummy.Next }

标签:head,随想录,fast,Next,链表,节点,指针
From: https://www.cnblogs.com/suxinmian/p/18001116

相关文章

  • Solution Set - 训练计划 链表
    咕掉了两道不可做题(指黑色)。梦幻布丁放在链表的题单里,和链表有什么关系呢???因为都是在对颜色整体进行操作,我们可以根据颜色拉出来对应的链表。那么每次合并就相当于把一个链表接到另一个链表上去,暴力修改,那么是\(O(n)\)的,但是要怎么维护答案呢?首先可以处理出不做任何操作时的......
  • 节点与链表
    classListNode:def__init__(self,val=0,next=None):self.val=valself.next=nextclassSingleLinkList:def__init__(self,node=None):self.__head=nodedefis_empty(self):'''判断列表是否为空'&#......
  • 代码随想录算法训练营第八天| 344.反转字符串 541. 反转字符串II 卡码网:54.替换数字
    反转字符串编写一个函数,其作用是将输入的字符串反转过来。输入字符串以字符数组 s 的形式给出。不要给另外的数组分配额外的空间,你必须原地修改输入数组、使用O(1)的额外空间解决这一问题。题目链接:344.反转字符串-力扣(LeetCode)关于是否用reverse函数解决问题:如果题目......
  • 动力节点RabbitMQ教程|12小时学会rabbitmq消息中间件-02
    RabbitMQ集群cluster与高可用RabbitMQ的集群分两种模式,一种是默认集群模式,一种是镜像集群模式;在RabbitMQ集群中所有的节点(一个节点就是一个RabbitMQ的broker服务器)被归为两类:一类是磁盘节点,一类是内存节点;磁盘节点会把集群的所有信息(比如交换机、绑定、队列等信息)持久化......
  • 代码随想录 day36 无重叠区间 划分字母区间 合并区间
    无重叠区间这里的思路是找到有几个非重叠区间然后总数减去非重叠区间就是剩下的重叠区间数首先排好序按左或者右都可以这里按左排好然后发现边界不重叠就++边界重叠那么由于左边界优先对齐了所以右边界更新作为一个新的整体区间和下一个区间比较划分字母区间......
  • 在K8S中,flannel能固定节点IP和Pod的IP地址吗?
    Flannel作为一个Kubernetes集群的网络插件,其设计目标之一是为Pod分配固定的IP地址,并确保不同节点上的PodIP地址不会冲突。具体来说:PodIP固定:Flannel在每个节点上预分配一个子网供Pod使用,当创建新Pod时,Flannel会从该节点的子网中分配一个唯一的IP地址给Pod,从而确保Pod在整个生......
  • 代码随想录算法训练营第三天 |203.移除链表元素 , 707.设计链表,206.反转链表
    206.反转链表 已解答简单 相关标签相关企业 给你单链表的头节点 head ,请你反转链表,并返回反转后的链表。 示例1:输入:head=[1,2,3,4,5]输出:[5,4,3,2,1]示例2:输入:head=[1,2]输出:[2,1]示例3:输入:head=[]输出:[] 提示:链......
  • 代码随想录 day35 柠檬水找零 根据身高重建队列 用最少数量的箭引爆气球
    柠檬水找零就根据几种条件列出来找零情况就行生活经验可知找零当然先给大面额的利于后面的找零根据身高重建队列这题感觉就是先做过队列给糖也难以有思路这里是先按身高先排好队一样身高就k小的排在前面然后再按他前面有几个人直接就给他插到第几个位置就行用最少......
  • 代码随想录算法训练营第七天| 454.四数相加II 383. 赎金信 15. 三数之和 18. 四
    454.四数相加II 给你四个整数数组 nums1、nums2、nums3 和 nums4 ,数组长度都是 n ,请你计算有多少个元组 (i,j,k,l) 能满足:0<=i,j,k,l<nnums1[i]+nums2[j]+nums3[k]+nums4[l]==0题目链接:454.四数相加II-力扣(LeetCode)思路:当遇到需要确认元素是......
  • 代码随想录算法训练营第六天 |242. 有效的字母异位词 349. 两个数组的交集 202. 快乐
    1.两数之和 已解答简单 相关标签相关企业 提示 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。你可以假设每种输入只会对应一个答案。但是,数组中同......