思路
比较简单的思路是可以使用两个指针,一个指针向后走,每走一步,使用另外一个指针从前遍历,查看是否有重复的指针。
实现
单链表成环只有一种情况:尾部节点指向前序已有节点
代码如下:
struct ListNode {
int val;
ListNode* next;
ListNode(int x) : val(x), next(NULL) {}
};
class Solution {
public:
bool hasCycle(ListNode* head) {
if (!head) return false;
// 声明必要变量
ListNode* bak = head;
ListNode* scan = head;
// head != nullptr
while (bak->next) {
// 扫描链表
if (bak == bak->next) return true;
/* 内循环终止条件:1. scan == head; 2. scan = head.next; return true
*/
scan = head;
while (scan != bak) {
if (scan == bak->next) return true;
scan = scan->next;
}
bak = bak->next;
}
return false;
}
}; 测试
附上测试代码(gtest):
TEST(List, ListCircle
) {
// 无循环链表
ListNode noCircle(10);
ListNode noCircle1(10);
ListNode noCircle2(10);
ListNode noCircle3(10);
noCircle.next = &noCircle1;
noCircle1.next = &noCircle2;
noCircle2.next = &noCircle3;
// 有循环链表
ListNode hasCircle(10);
ListNode hasCircle1(10);
ListNode hasCircle2(10);
hasCircle.next = &hasCircle1;
hasCircle1.next = &hasCircle2;
hasCircle2.next = &hasCircle1;
// 创建检测对象
Solution sol;
EXPECT_FALSE(sol.hasCycle(&noCircle)
);
EXPECT_TRUE(sol.hasCycle(&hasCircle)
);
} 
京公网安备 11010502036488号