2020-3-27
- It’s easy to find if you know what you are looking for.
如果知道自己想追求什么,找到目标就容易了。
题目:
给定一个链表,判断链表中是否有环。
为了表示给定链表中的环,我们使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。
如果 pos 是 -1,则在该链表中没有环。
- 示例 1:
输入:head = [3,2,0,-4], pos = 1
输出:true
解释:链表中有一个环,其尾部连接到第二个节点。
- 示例 2:
输入:head = [1,2], pos = 0
输出:true
解释:链表中有一个环,其尾部连接到第一个节点。
- 示例 3:
输入:head = [1], pos = -1
输出:false
解释:链表中没有环。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/linked-list-cycle
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
个人解答:(C版本)
- 首先通过哪种值来判断是否回环?毋庸置疑,是每个节点的地址,这个是唯一的,也就是说当后面的节点指向前面的节点时,就是回环。要记住前面每一个节点的地址,需要很多的内存才能够实现。
- 所以想到一种做法,因为每个节点都有一个值,我们可以在这个上做文章。从头开始遍历,我们让第一个节点的值为0,到第二节点的值时为1,依次这样下去。
在遍历的过程中,我们不断判断即将遍历的节点的值是多少,如果其值小于等于前一个节点的值且大于0(我们赋予的第一个节点的值),那么这个值很有可能是回环的节点,我们找到前面也是这个值的指针,然后比较两者是否相等。
若相等,则说明回环。
若不相等,继续按之前的方式继续遍历,继续累增赋值,最后找到回环的点,或者找到NULL(说明不存在回环)
详细看下面的代码。
/**
* Definition for singly-linked list.
* struct ListNode {
* int val;
* struct ListNode *next;
* };
*/
bool hasCycle(struct ListNode *head) {
int i = 0;
struct ListNode *q = head;
if(NULL == q)
return false;
while(1)
{
q->val = i;
q = q->next;
if(NULL == q)
return false;
if((q->val <= i) && (q->val >= 0))
{
struct ListNode *p = head;
for(int j=0; j<(q->val); j++)
{
p = p->next;
}
if(p == q)
return true;
}
i++;
}
}
- 复杂度分析
1)循环套循环,所以该算法的时间复杂度为O(n^2)。
2)由于只使用了少量的变量,空间复杂度为O(1)。
- 运行结果: