LeetCode刷题:Linked List Cycle 及其进阶Linked List Cycle II
2016-05-05 16:54
337 查看
Given a linked list, determine if it has a cycle in it.
Follow up:
Can you solve it without using extra space?
1. 首先解决的问题是 判断单链表 有没有环?
解题思路:
两个指针slow 和 fast,开始都指向 head, slow指针每次走一步,fast 指针每次走两步,看看最终 slow 和 fast 会不会重合,如果 链表有环,那么一定会重合。
2. 问题进阶: 如果链表有环,返回环开始的那个节点, 该怎么做呢?
LeetCode 上的问题:
Given a linked list, return the node where the cycle begins. If there is no cycle, return
Note: Do not modify the linked list.
Follow up:
Can you solve it without using extra space?
引用网上的一张图:
Like the picture shows above: assume linked list has cycle,the length of cycle is Y,the length outside cycle is X.
Two
pointers, one goes one step per time, another goes two steps per time. If they went t times and meet at the K node.
ponter 1 每次走一步,pointer 2 每次走两步, 下面公式中的t 代表每个pointer总的路程:
for pointer 1: t = X+nY+K
for pointer 2: 2t = X+mY+K (m,n is unknown)
From above equation, we could get:
2X + 2nY + 2K = X + mY + K
=> X+K = (m-2n)Y
所以 X+K 等于 Y 的整数倍。
所以有下面的结论(数学问题,我还是不太能理解):
It is clear that the relationship between X and K is complementary based on Y.
Which is to say, if pointer 1 goes X steps from start node and pointer 2 goes X steps form K node. They will meet at the start place of cycle.
Complexity is O(n)
反正就是: pointer 1 和 pointer 2 找到重合点K 后,那么 pinter 1 返回起点head, pointer 2 从K处继续走,他们一定会在环的起始点相遇。
这个我试了几组,确实是这样的。
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
//if(head == NULL || head->next == NULL)
//{
// return NULL;
//}
ListNode *slow, *fast;
slow = fast = head;
//fast = fast->next;
while(fast!=NULL && fast->next !=NULL)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
{
break;
}
//fast = fast->next;
}
if (fast == NULL || fast->next == NULL)
{
return NULL;
}
//has cycles, so find the cycle start point.
slow = head;
if(slow->next == fast)
{
return slow;
}
while(slow != fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
};
Follow up:
Can you solve it without using extra space?
1. 首先解决的问题是 判断单链表 有没有环?
解题思路:
两个指针slow 和 fast,开始都指向 head, slow指针每次走一步,fast 指针每次走两步,看看最终 slow 和 fast 会不会重合,如果 链表有环,那么一定会重合。
/** * Definition for singly-linked list. * struct ListNode { * int val; * ListNode *next; * ListNode(int x) : val(x), next(NULL) {} * }; */ class Solution { public: bool hasCycle(ListNode *head) { if(head == NULL || head->next == NULL) { return false; } ListNode *slow, *fast; slow = fast = head; //fast = fast->next; while( fast != NULL && fast->next != NULL) { fast = fast->next; if (slow == fast) { return true; } slow = slow->next; fast = fast->next; } if(fast == NULL || fast->next == NULL) { return false; } else { return false; } } };
2. 问题进阶: 如果链表有环,返回环开始的那个节点, 该怎么做呢?
LeetCode 上的问题:
Given a linked list, return the node where the cycle begins. If there is no cycle, return
null.
Note: Do not modify the linked list.
Follow up:
Can you solve it without using extra space?
引用网上的一张图:
Like the picture shows above: assume linked list has cycle,the length of cycle is Y,the length outside cycle is X.
Two
pointers, one goes one step per time, another goes two steps per time. If they went t times and meet at the K node.
ponter 1 每次走一步,pointer 2 每次走两步, 下面公式中的t 代表每个pointer总的路程:
for pointer 1: t = X+nY+K
for pointer 2: 2t = X+mY+K (m,n is unknown)
From above equation, we could get:
2X + 2nY + 2K = X + mY + K
=> X+K = (m-2n)Y
所以 X+K 等于 Y 的整数倍。
所以有下面的结论(数学问题,我还是不太能理解):
It is clear that the relationship between X and K is complementary based on Y.
Which is to say, if pointer 1 goes X steps from start node and pointer 2 goes X steps form K node. They will meet at the start place of cycle.
Complexity is O(n)
反正就是: pointer 1 和 pointer 2 找到重合点K 后,那么 pinter 1 返回起点head, pointer 2 从K处继续走,他们一定会在环的起始点相遇。
这个我试了几组,确实是这样的。
代码如下:
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* ListNode *next;
* ListNode(int x) : val(x), next(NULL) {}
* };
*/
class Solution {
public:
ListNode *detectCycle(ListNode *head) {
//if(head == NULL || head->next == NULL)
//{
// return NULL;
//}
ListNode *slow, *fast;
slow = fast = head;
//fast = fast->next;
while(fast!=NULL && fast->next !=NULL)
{
slow = slow->next;
fast = fast->next->next;
if(slow == fast)
{
break;
}
//fast = fast->next;
}
if (fast == NULL || fast->next == NULL)
{
return NULL;
}
//has cycles, so find the cycle start point.
slow = head;
if(slow->next == fast)
{
return slow;
}
while(slow != fast)
{
slow = slow->next;
fast = fast->next;
}
return slow;
}
};
相关文章推荐
- Java设计模式之代理模式
- 编写自己的JDBC框架
- 关于JSON的格式
- Android中应用程序如何获得系统签名权限
- 计算机视觉/机器学习/深度学习预备知识
- 重力加速度陀螺仪传感器MPU-6050
- 好RESTful API的设计原则
- c++ 多态
- mjRefresh使用指南
- 如何用ps来切分图片
- swift 监听键盘状态
- 程序员技术练级攻略
- awk支持多个记录分隔符的写法
- IE hack
- 适合于小团队产品迭代的APP测试流程
- 修复 Sync with Gradle for project ' ' failed: 拒绝连接问题
- Javascript Unicode转换函数
- 多线程—wait,notify(针对方法synchronized)
- 欢迎使用CSDN-markdown编辑器
- hcatalog简介和使用