题意理解
找一个链表中环形的起始结点位置。
问题分析
链表
hash表法
双指针法,快慢指针,每次一步,每次两步。如果快慢指针相遇,说明有环;从相遇点到环开始点的距离和从表头到环开始点的距离相同。
其他
hash表好想好实现,但是空间消耗O(n);双指针法不好想(尤其是找换开始结点),但是空间消耗低O(1).
链接
ListNode *detectCycle(ListNode *head) {
ListNode* slow; //慢指针,每次一步
ListNode* fast; //快指针,每次两步
if (!head || !head -> next || !head -> next -> next) //判断快指针两步是不是能走
return NULL;
fast = head -> next -> next; //快指针走两步
slow = head -> next; //慢指针走一步 必须先走,否则循环判断条件重合
while (slow != fast) //如果快、慢指针不等
{
if (!fast || !fast -> next) //判断快指针两步能不能走到
return NULL;
slow = slow -> next; //慢指针走
fast = fast -> next -> next; //快指针走
}
fast = head; //快慢指针相等,说明有环;重新利用快指针从头开始走
while (slow != fast) //两指针相遇点为环的起始点
{
slow = slow -> next;
fast = fast -> next;
cout << 2 << endl;
}
return slow;
}
hash表法
ListNode *detectCycle(ListNode *head) {
map<ListNode*, int> dict; //记录每个结点出现的次数
ListNode* p = head;
while(p) //链表不空
{
if (dict.find(p) == dict.end()) //字典找不到
{
dict[p] ++; //字典增加这个结点的字典项
}
else
{
return p; //找到即为重复
}
p = p -> next; //链表后移
}
return NULL; //链表遍历完,说明没有环
}