题目:
Given a linked list, determine if it has a cycle in it.
Can you solve it without using extra space?
解答:
乍一看很简单。我的做法是保存头指针,然后另一个指针继续遍历下去,直到遇到头指针为止。但是我没有考虑到部分回环情况:
说实话我并没有想到什么好办法。直到看了Discussion,发现可以有追击问题的思路来做:一个慢指针一次跑一步,一个快指针一次跑两步。如果有环一定能追上。
于是我写下:
class Solution { public: bool hasCycle(ListNode *head) { if(head == NULL || head->next == NULL || head->next->next == NULL) return false; ListNode* slow = head->next; ListNode* fast = head->next->next; while(slow != NULL) { if(slow == fast) { return true; } if(fast->next->next == NULL) { return false; } else { slow = slow->next; fast = fast->next->next; } } return false; } };
显示Runtime Error……后来发现,当判断 if(fast->next->next == NULL) 的时候,我忘记了考虑了:如果 fast->next == NULL,那 fast->next->next 就变成了野指针,然后else里面将野指针赋值给 fast 就没尽头了。
将判断 if(fast->next->next == NULL) 改为了 if (fast->next->next == NULL || fast->next == NULL),还是错……
这时基本功暴露了……条件“或”操作是短路操作。而 fast->next == NULL 是需要提前判断的条件,所以应该提前判断。最终AC版本:
class Solution { public: bool hasCycle(ListNode *head) { if(head == NULL || head->next == NULL || head->next->next == NULL) return false; ListNode* slow = head->next; ListNode* fast = head->next->next; while(slow != NULL) { if(slow == fast) { return true; } if(fast->next == NULL || fast->next->next == NULL) { return false; } else { slow = slow->next; fast = fast->next->next; } } return false; } };
时间: 2024-10-08 14:52:26