★ Linked List Cycle II -- LeetCode
2023-09-27 14:27:00 时间
证明单链表有环路:
本文所用的算法 能够 形象的比喻就是在操场其中跑步。速度快的会把速度慢的扣圈
能够证明,p2追赶上p1的时候。p1一定还没有走完一遍环路,p2也不会跨越p1多圈才追上
我们能够从p2和p1的位置差距来证明。p2一定会赶上p1可是不会跳过p1的
由于p2每次走2步。而p1走一步。所以他们之间的差距是一步一步的缩小,4,3,2,1,0
到0的时候就重合了。
找到环路的起点:
既然可以推断出是否是有环路,那改怎样找到这个环路的入口呢?
解法例如以下: 当p2依照每次2步,p1每次一步的方式走,发现p2和p1重合,确定了单向链表有
环路了。
接下来。让p2回到链表的头部。又一次走,每次步长不是走2了,而是走1。那么当p1和p2再次
相遇的时候。就是环路的入口了。
这点能够证明的:
在p2和p1第一次相遇的时候,假定p1走了n步骤,环路的入口是在p步的时候经过的,那么有
1、p1走的路径: p+c = n; c为p1和p2相交点,距离环路入口的距离。
2、p2走的路径: p+c+k*L = 2*n。 L为环路的周长,k是整数;
将1式中的p+c=n代入到2式,整理得:n=k*L;
所以,假设从p+c点開始,p1再走n步骤的话,还能够回到p+c这个点
同一时候p2从头開始走的话。经过n不,也会达到p+c这点
显然在这个步骤其中p1和p2仅仅有前p步骤走的路径不同,所以当p1和p2再次重合的时候。必
然是在链表的环路入口点上。
code
//Given a linked list, return the node where the cycle begins. If there is no cycle, return null. #include<iostream> #include<fstream> using namespace std; struct ListNode { int val; ListNode *next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: ListNode *detectCycle(ListNode *head) { ListNode* fast_walker = head; if (has_cycle(head, fast_walker)){ ListNode* cur = head; while (fast_walker != cur){ fast_walker = fast_walker->next; cur = cur->next; } return cur; } else return NULL; } private: bool has_cycle(ListNode* head , ListNode* fast_walker){ ListNode* slow_walker = head; while (slow_walker && fast_walker){ fast_walker = fast_walker->next; if (fast_walker) fast_walker = fast_walker->next; else break; slow_walker = slow_walker->next; if (fast_walker == slow_walker) return true; } return false; } }; int main(){ fstream fin("test.txt"); ListNode* head(0);//此时并没有分配存储地址 ListNode* tmp = head;//此时相当于 tmp = NULL int in = 0; while (fin >> in){ if (!head) { head = new ListNode(in); tmp = head; } else{ while (tmp->next != NULL) tmp = tmp->next; tmp->next = new ListNode(in); tmp = tmp->next; tmp->next = NULL; } } //制造一个环 tmp->next = head->next; Solution ss; ListNode* retult = ss.detectCycle(head); system("pause"); return 0; }
相关文章
- 【LeetCode】除自身以外数组的乘积 [M](数组)
- LeetCode_动态规划_343.整数拆分
- LeetCode_双指针_二分搜索_简单_392.判断子序列
- LeetCode·每日一题·1144.递减元素使数组呈锯齿状·模拟
- LeetCode·每日一题·1812.判断国际象棋棋盘中一个格子的颜色·数学
- LeetCode·每日一题·1302.层数最深叶子节点的和·DFS·BFS
- 【LeetCode】【Python】Linked List Cycle
- Remove Duplicates from Sorted List II--LeetCode
- leetcode先刷_Remove Duplicates from Sorted List II
- 【LeetCode从零单排】No 114 Flatten Binary Tree to Linked List
- LeetCode || Copy List with Random Pointer
- [LeetCode] 624. Maximum Distance in Arrays 数组中的最大距离
- [LeetCode] 52. N-Queens II N皇后问题 II
- [LeetCode] 650. 2 Keys Keyboard 两键的键盘
- [LeetCode] 142. Linked List Cycle II 链表中的环 II
- [LeetCode] 141. Linked List Cycle 链表中的环
- [LeetCode] 341. Flatten Nested List Iterator 压平嵌套链表迭代器
- leetcode 1382 将二叉搜索树变平衡
- leetcode 226 翻转二叉树
- leetcode 454 四数相加II