首页 > 编程语言 >Floyd判圈算法 leetcode

Floyd判圈算法 leetcode

时间:2024-06-03 19:57:15浏览次数:25  
标签:指向 判圈 相遇 距离 leetcode 链表 Floyd 节点 指针

龟兔赛跑 / Floyd判圈算法概述

(对应力扣142. 环形链表 II,141. 环形链表 I)

判断一个链表是否存在环

龟兔赛跑 / Floyd判圈算法 转换成判断链表是否存在 “环” 问题可以总结以下三点:

  1. 定义两个指针(慢指针和快指针),初始时都指向链表的头节点。
  2. 两个指针以不同速度移动(一个快一个慢).
  3. 如果链表中存在环,快指针和慢指针最终会相遇(指向同一个节点),否则快指针会到达链表的末尾(指向NULL)。

满足这三个条件之后,只要链表存在"环",那么速度快的指针速度慢的指针一定会相遇(指向同一处节点即为相遇),并且被两个指针所指向的这个节点一定是在链表中的"环"的起点以及"环"的起点之后中的位置!


注释 :可能有人会疑问:快指针有可能会跳过慢指针,以致两个指针不会相遇(指向同一个节点)。这种情况确实存在.
但在实际操作中(判断链表是否存在环),我们通常定义快指针每次移动两个节点慢指针每次移动一个节点。这样,即使快指针会跳过某些节点,慢指针会遍历到所有节点,最终快指针和慢指针一定会在某处相遇。


画图演示两个指针相遇的情况:

  • 速度的指针为蓝色三角形
  • 速度的指针为紫色三角形
//p 为慢指针, q 为快指针
while(q != NULL &&  q->next!=NULL){
p = p->next;
q = q->next->next;
if(p == q) {
 //后续操作处理.....
 }
} 
  • 开始两个指针都指向头节点(head)
    在这里插入图片描述

  • 后面每一次循环,快指针移动个距离,慢指针移动个距离
    在这里插入图片描述

  • 循环继续
    在这里插入图片描述

  • 到这里两个指针指向的节点相同,就可以做后续的处理了
    在这里插入图片描述

查找链表中环的首个节点

我们可以通过上面的方法判断链表中是否存在环
那么如何找到环的首个节点?
我们继续使用上面的例子
在这里插入图片描述
我们定义:

  1. head到环的起始节点的距离为a,环的起始节点到相遇节点的距离为b,相遇节点到环的起始节点的距离为c。
  2. 当快慢指针相遇时,快指针已经绕环n圈。
    (因为这里是单链表,只有next指针,不能从后向前访问,所以只能用指向后一项的指针)

在这里插入图片描述

注意这里的while循环,快指针慢指针速度的两倍,也就是相同的时间内(同一个循环中)快指针移动的距离是慢指针移动的距离的两倍


数学公式表示为:

(n 为链表中快指指针从环的起始点绕一圈的次数)

慢指针的距离为: a+b
快指针的距离为: 2(a+b)

根据上面的对距离的定义还可以得出:
q= (a+b) + (b+c)*n
即得出方程
2(a+b) = (a+b) + (b+c)*n
2a+2b = a+b+nb+nc
a = - b+nb+nc
a = - b+nb+nc+c - c
a = (n-1)b + (n-1)c +c
a = (n-1)(b+c) + c

  • 此时如果n为1(当n=1时,表示快指针绕环一次),可以得出结论 a = c 即:
    头节点 到 环的起始节点的距离 = 两个指针相遇的节点 到 环的起始点的距离.
    换言之,头节点到链表中环的起始节点的距离等于两个指针相遇的节点到环的起始节点的距离。因此,无论在环中循环多少次,这两个距离始终相同。

标签:指向,判圈,相遇,距离,leetcode,链表,Floyd,节点,指针
From: https://blog.csdn.net/2301_80379205/article/details/139413319

相关文章

  • LeetCode 1168. Optimize Water Distribution in a Village
    原题链接在这里:https://leetcode.com/problems/optimize-water-distribution-in-a-village/description/题目:Thereare n housesinavillage.Wewanttosupplywaterforallthehousesbybuildingwellsandlayingpipes.Foreachhouse i,wecaneitherbuildaw......
  • LeetCode 720. Longest Word in Dictionary
    原题链接在这里:https://leetcode.com/problems/longest-word-in-dictionary/description/题目:Givenanarrayofstrings words representinganEnglishDictionary,return thelongestwordin words thatcanbebuiltonecharacteratatimebyotherwordsin wor......
  • leetcode第263题:丑数
    丑数的因子只能是2,3,5。但是可能有多个2,多个3,多个5.因此需要循环地除以2、3、5.publicclassSolution{publicboolIsUgly(intn){if(n<=0){returnfalse;}int[]factors={2,3,5};for(inti=0;i......
  • leetcode第1281题: 整数的各位积和之差
    publicclassSolution{publicintSubtractProductAndSum(intn){intsum=0;intji=1;while(n>0){intnum=n%10;sum+=num;ji*=num;n/=10;}returnji-sum;......
  • LeetCode 1151. 最少交换次数来组合所有的 1
    1151.最少交换次数来组合所有的1给出一个二进制数组 data,你需要通过交换位置,将数组中 任何位置 上的1组合到一起,并返回所有可能中所需 最少的交换次数。示例1:输入:data=[1,0,1,0,1]输出:1解释:有三种可能的方法可以把所有的1组合在一起:[1,1,1,0,0],交换......
  • LeetCode 1411. Number of Ways to Paint N × 3 Grid
    原题链接在这里:https://leetcode.com/problems/number-of-ways-to-paint-n-3-grid/description/题目:Youhavea grid ofsize nx3 andyouwanttopainteachcellofthegridwithexactlyoneofthethreecolors: Red, Yellow, or Green whilemakingsuretha......
  • leetcode 60 排列序列
    排列序列已解答困难相关标签相关企业给出集合[1,2,3,...,n],其所有元素共有n!种排列。按大小顺序列出所有排列情况,并一一标记,当n=3时,所有排列如下:"123""132""213""231""312""321"给定n和k,返回第k个排列。示例1:输入:n=3,k=3输出:"213"示......
  • Leetcode 3171. Find Subarray With Bitwise AND Closest to K
    Leetcode3171.FindSubarrayWithBitwiseANDClosesttoK1.解题思路2.代码实现题目链接:3171.FindSubarrayWithBitwiseANDClosesttoK1.解题思路这道题坦率地说让我感觉很挫败,又一次没有自力搞定,是看了大佬们的答案才搞定的……知道比没有搞定更难受的......
  • leetcode-280. 摆动数组
    给你一个的整数数组nums,将该数组重新排序后使nums[0]<=nums[1]>=nums[2]<=nums[3]...简单想法排序双指针,一前一后插入贪心?猜的假定前i个已经摆动,i+1存在奇、偶两种情况奇数——若nums[i+1]>=nums[i+2]则符合条件,若nums[i+1]<nums[i+2],尝试交换......
  • LeetCode //C - 147. Insertion Sort List
    147.InsertionSortListGiventheheadofasinglylinkedlist,sortthelistusinginsertionsort,andreturnthesortedlist’shead.Thestepsoftheinsertionsortalgorithm:Insertionsortiterates,consumingoneinputelementeachrepetitionand......