题目
给定一个链表,判断是否循环链表。
后续:
你的解决方案能够不使用额外的(内存)空间吗?
难度:容易
编程语言:C++
分析
程序框架为:
1 2 3 4 5 6 7 8 9 10 11 12 13
| // 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) { } };
|
最简单的思路是:
- 使用一个 map 记录所有链表节点
- 每遍历一个节点,检查 map 是否已存在该节点
- 如果已存在,说明是循环链表
- 如果不存在,添加该节点到 map
- 一直遍历链表节点,直到出现循环,或到达链表尾
伪代码如下:
1 2 3 4 5 6 7 8 9 10 11
| bool hasCycle(ListNode* head) { map<ListNode*, bool> mapp; while (head != NULL) { if (mapp.find(head) != mapp.end()) { // head 已存在 return true; } mapp[head] = true; head = head->next; } return false; }
|
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48
| #include <iostream> #include <map> using namespace std; struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: bool hasCycle(ListNode* head) { map<ListNode*, bool> mapp; while (head != NULL) { if (mapp.find(head) != mapp.end()) { return true; } mapp[head] = true; head = head->next; } return false; } }; int main() { ListNode n1(1); ListNode n2(2); ListNode n3(3); ListNode n4(4); ListNode n5(5); ListNode n6(6); ListNode n7(7); n1.next = &n2; n2.next = &n3; n3.next = &n4; n4.next = &n5; n5.next = &n6; n6.next = &n1; Solution sol; cout << sol.hasCycle(&n1) << endl; }
|
提交到 Leetcode,Accepted! :) 运行时间为 60ms。
后续
你的解决方案能够不使用额外的(内存)空间吗?
我实在想不到 O(1) 空间复杂度的算法,参考这篇文章的思路:
- 用两个指针 pi, pi2 遍历链表,pi 每次走一步,pi2 每次走两步。
- 如果 pi2 先走到链表尾,说明不是循环链表。
- 如果 pi2(走了一圈后)与 pi相遇,说明是循环链表。
代码如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83
| #include <iostream> #include <map> using namespace std; struct ListNode { int val; ListNode* next; ListNode(int x) : val(x), next(NULL) {} }; class Solution { public: bool hasCycle2(ListNode* head) { if (head == NULL) { return false; } ListNode* pi = head; ListNode* pi2 = head; while (true) { if (pi->next != NULL) { pi = pi->next; } else { return false; } if (pi2->next != NULL) { if (pi2->next->next != NULL) { pi2 = pi2->next->next; } else { return false; } } else { return false; } if (pi == pi2) { return true; } } } }; int main() { ListNode n1(1); ListNode n2(2); ListNode n3(3); ListNode n4(4); ListNode n5(5); n1.next = &n2; n2.next = &n3; n3.next = &n4; n4.next = &n5; n5.next = &n1; Solution sol; cout << sol.hasCycle2(&n1) << endl; }
|
提交到 Leetcode,Accepted! :) 运行时间为 12ms。