首页 > 其他分享 >剑指Offer——链表的环以及环的入口

剑指Offer——链表的环以及环的入口

时间:2022-12-19 13:36:14浏览次数:38  
标签:结点 slow Offer fast next 链表 pHead 入口 指针

在一个排序的链表中,存在重复的结点,请删除该链表中重复的结点,重复的结点不保留,返回链表头指针。 例如,链表1->2->3->3->4->4->5 处理后为 1->2->5

解题思路

这个题包含两个子问题,一个是判断链表是否有环,另一个是如果有环,找到环的入口。

  1. 对于如何判断链表有环问题,较为基础:快慢指针。
  2. 对于如何找到环的入口,这个地方需要推导一下:
    x表示头结点到入口结点的距离,表示入口结点到fast和slow相遇结点的距离,z是环中剩下的长度,即有z+y=L。L表示的是环的长度。那么当快慢指针相遇时候有:S = x+y 2*S = x+y+nL。即,慢指针走过x+y的结点,快指针比慢指针多走了n圈。这里慢指针在环中也可能多走了几圈才相遇的,但是可以不用表示出来。因为快指针的nL表示的就是比慢指针多走的圈数。举例:慢指针如果走 x+y+2L,快指针走 x+y+4L 那么就可以写成:慢x+y 快x+y+2L.是等价的。

    消去s,可得,同时:,代入消去y,可得

如图

剑指Offer——链表的环以及环的入口_头结点

得到

能说明什么问题呢?

走x步,等于走 n-1圈再走上z步。走x步,正好就是从头结点到环入口结点。而z步是从相遇地方,到入口结点,在加上多少圈,实际走的都是从相遇到入口结点。举个例子,如果n = 1,那么x=z。如果n=2,那么x=L+z.就是多走一圈到相遇结点,然后再走z步还是到环的入口结点。

这个时候,我们只需要令一个结点从头结点出发,走x步,另一个结点从相遇结点出发,走n圈(n=0,1,2,...)再走z步,他们会同时到达环的入口地方。

题解

public ListNode EntryNodeOfLoop(ListNode pHead)
{
if(pHead == null) return null;
if (isLoop(pHead)){
ListNode slow = pHead.next;
ListNode fast = pHead.next.next;

while(slow != fast){
slow = slow.next;
fast = fast.next.next;
}
// 循环结束时候 slow == fast
slow = pHead;
// 一个从头开始走 ,一个从相遇地方开始走,走同样的步数
// 因为 x= z+(n-1)L
while(slow != fast){
slow = slow.next;
fast = fast.next;
}
return slow;
}
else return null;
}
public boolean isLoop(ListNode pHead){
if (pHead.next == null) return false;
ListNode slow = pHead;
ListNode fast = pHead;
while (fast != null && fast.next !=null){
slow = slow.next;
fast = fast.next.next;
if (slow == fast){
return true;
}
}
return false;
}

 

标签:结点,slow,Offer,fast,next,链表,pHead,入口,指针
From: https://blog.51cto.com/u_15730090/5951930

相关文章

  • 数据结构 玩转数据结构 7-2 基于链表的集合实现
    0课程地址https://coding.imooc.com/lesson/207.html#mid=13704 1重点关注1.1使用链表实现集合Set详见3.1用链表实现的集合  2......
  • 从redis源码看数据结构(一)链表
    文章目录​​从redis源码看数据结构(一)链表​​​​一,redis数据类型​​​​二,redis底层列表实现​​​​1.列表底层数据结构​​​​2.redis双向链表操作​​​​新建链表​......
  • 链表与数组的区别
    原文链接:https://baijiahao.baidu.com/s?id=1743478279629141019物理存储结构不同链表与数组在计算机中存储元素采用不同的物理存储结构,数组是顺序存储结构,链表是链式......
  • 链表--删除无序链表中重复的节点
    题目:给定一个无顺序单链表的头节点head,删除其中值重复的元素思路:利用哈希表。生成一个哈希表,因为头节点是没有必要去删除的节点,所以首先将头节点放入哈希表;从头......
  • redis底层数据结构之双向链表(linkedlist)
    双向链表(linkedlist)redis的双向链表(linkedlist)是基于链表的一种数据结构链表是一种常见的基础数据结构,是一种非顺序存储数据的线性表,在每一个节点里存储了下一个节点......
  • 链表经典问题
    链表经典问题1.反转链表问题:将链表反转,并返回新的头节点。思路:设置两个指针,反别表示现节点和前节点,遍历链表,同时设置一个临时指针储存下一个节点。然后让现指针的next指......
  • 结构体&指针&链表
    一.结构体0.前言我们所学过的类型如:char,int,float,double等,都只能描述单一变量。但是结构体,顾名思义,是多个变量的集合,其中包含多个单一变量。所以C语言就发明了结构体用......
  • 代码随想录-链表
    链表链表--移除链表元素题目:力扣题目链接题意:删除链表中等于给定值val的所有节点。示例1:输入:head=[1,2,6,3,4,5,6],val=6输出:[1,2,3,4,5]示例2:输入:head=......
  • 老男孩教育 | 已婚已育,30岁0基础转行,成功收获满意的Offer!
    不够优秀,努力来凑~~~不要为懒散和懈怠找任何理由,每天给自己一个希望,路是靠自己走出来的,成功是靠自己努力得到的!!!俗话说:二十而冠,三十而立!30岁是人生分水岭,步......
  • 【LeeCode】链表的学习
    基础知识​​学习参考​​importjava.util.*;//JAVA链表classNode{publicintdata;publicNodenext;publicNode(intdata){this.data=data;......