目录
环形链表 I
题目
思路分析
对于这道题,我们使用快慢指针法。定义两个指针,一快一慢,初始位置在head。慢指针每次只移动一步,而快指针每次移动两步。所以快指针必定先于慢指针进入环,当快指针追上慢指针时,说明该链表存在环,否则快指针到达链表末尾,不存在环。
完整代码
typedef struct ListNode LNode;
bool hasCycle(struct ListNode *head)
{
LNode* slow, *fast;
slow = fast = head;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(fast == slow)
{
return true;
}
}
return false;
}
注意这里while循环的条件不能调换,否则就会出现解引用空指针的错误。
时间复杂度:O(N)
空间复杂度:O(1)
环形链表 II
题目
思路分析
这一题与上面的题类似,但难度比上一题稍大。
我们还是使用快慢指针,两个指针重新相遇,说明链表存在环,否则就不存在,返回NULL。
然后在额外定义一个指向head的ptr指针,让它和slow每次向后移动一个节点。最终,它们会在入环点相遇。
下面为leetcode官方给出的证明
最关键的还是在于证明了,从相遇点到入环点的距离加上 n−1 圈的环长 == 从链表头部到入环点的距离。
完整代码
typedef struct ListNode LNode;
struct ListNode *detectCycle(struct ListNode *head)
{
LNode* slow,*fast;
slow = fast = head;
while(fast && fast->next)
{
fast = fast->next->next;
slow = slow->next;
if(slow == fast)
{
LNode* ptr = head;
while(ptr != slow)
{
slow = slow->next;
ptr = ptr->next;
}
return ptr;
}
}
return NULL;
}
时间复杂度:O(N)
空间复杂度:O(1)
拜拜,下期再见😏
摸鱼摸鱼😴✨🎞