弗洛伊德判圈算法
来源:互联网 发布:ios开源项目源码 编辑:程序博客网 时间:2024/04/29 22:19
先来看链表是否有环的判断设链表起始节点为H,回路起始节点为S,两指针第一次相遇节点为M。设回路的长度为c,S到M的距离为c1,M到S的距离为c2。设H到S的距离为d。设hare每次移动2,tortoise每次移动1。移动k次后两者相遇。不难发现,H到M的距离为k。为了便于理解,请参考下图:由已知条件,可得到下列等式:hare和tortoise相遇时,hare套了tortoise若干圈。则有:2k – k = nc = k,n为正整数。从上图中定义的距离关系,可以得到c = c1 + c2k = d + c1由以上格式变换可得: d = nc – c1 = c2 + (n-1)c该式具有什么重要意义呢?假设2个指针分别从H和M出发,都是每次移动1的距离,他们会在哪里相遇?一个指针从H出发移动d后到达M。另一指针移动 c2 + (n-1)c,(n-1)c意味着绕了n-1圈又回到M,实际上相当于走了c2的距离,到达M。我们发现,两指针必然在S相遇。
代码如下:
public ListNode detectCycle(ListNode head) { if (head == null) return null; ListNode fast = head, slow = head; while (fast.next != null && fast.next.next != null) { slow = slow.next; fast = fast.next.next; if (slow == fast) { fast = head; while (fast!=slow){ fast=fast.next; slow = slow.next; } return fast; } } return null; }
再看一个问题
Given an array nums containing n + 1 integers where each integer is between 1 and n (inclusive), prove that at least one duplicate number must exist. Assume that there is only one duplicate number, find the duplicate one.
Note:
- You must not modify the array (assume the array is read only).
- You must use only constant, O(1) extra space.
- Your runtime complexity should be less than
O(n2)
. - There is only one duplicate number in the array, but it could be repeated more than once.
这个问题的限制条件比较多。不能修改数组元素,只能用常量空间,复杂度<
O(n2).
用鸽笼原理很好证明必有重复元素。把元素取值1到n看成n个笼子,n+1个数放到n个笼子必有重复。举个例子:
4,1,2,3,1
重复的元素构成环
1,2,3,4,5
4,1,2,3,1
1->4, 4->3,3->2,2->1所以1是重复的
int next(int array[], int num) { return array[num]; } public int findDuplicate(int[] nums) { int fast = nums[0], slow = nums[0]; while (true) { slow = next(nums, slow); fast = next(nums, next(nums, fast)); if (slow == fast) { fast = nums[0]; while (fast != slow) { fast = next(nums, fast); slow = next(nums, slow); } return fast; } } }
0 0
- 弗洛伊德判圈算法
- Floyd判圈算法
- Floyd判圈算法
- floyd判圈算法
- Floyd判圈算法
- Floyd 判圈 算法
- Floyd判圈算法
- Floyd判圈算法
- Floyd判圈算法
- floyd判圈算法
- Floyd 判圈算法
- 关于Floyd判圈算法
- Floyd判圈算法理解
- Floyd判圈算法【区庆亮】
- Floyd判圈算法理解
- Floyd判圈算法理解
- 算法-floyd判环(圈)算法
- UVA11549(Floyd判圈算法)
- XSS跨站脚本攻击剖析与防御
- 在两个activity之间传送数据
- Codeforces Round #324 (Div. 2)——C. Marina and Vasya
- 剑指offer—把字符串转换成整数
- ocp-210
- 弗洛伊德判圈算法
- 常用的开源游戏服务器框架
- 【读书笔记】iOS-GCD-网络编程要不要使用GCD
- c++中为什么用Send()或send()发送数据时要多发送至少一个字节
- ocp-211
- 万能药水(贪心)
- Tomcat6环境JBPM4.4报错:java.lang.ClassNotFoundException: de.odysseus.el.util.SimpleResolver
- Android常用辅助类(二)——设备相关
- C语言基础知识