方法一:哈希表
class Solution {
public:
bool hasCycle(ListNode *head) {
unordered_set<ListNode*> seen; // 创建一个无序集合来存储已经访问过的节点指针
while (head!= nullptr) { // 只要当前节点不为空,就继续循环
if (seen.count(head)) { // 如果集合中已经存在当前节点的指针,说明有环
return true; // 返回真,表示有环
}
seen.insert(head); // 将当前节点指针插入集合,表示已访问
head = head->next; // 移动到下一个节点
}
return false; // 如果遍历完链表都没有发现重复的节点,说明无环,返回假
}
};
方法二:乌龟兔子指针
class Solution {
public:
bool hasCycle(ListNode* head) {
if (head == nullptr || head->next == nullptr) {
return false;
}
// 考虑边界情况,如果链表为空或者只有一个节点,肯定无环
ListNode* slow = head; // 定义一个慢指针,每次移动一步
ListNode* fast = head->next; // 定义一个快指针,每次移动两步
while (slow!= fast) { // 当慢指针和快指针不相遇时,继续循环
if (fast == nullptr || fast->next == nullptr) {
return false;
}
// 如果快指针到达链表末尾(为空或者下一个节点为空)(为防止fast下一个节点不能被访问到)说明无环
slow = slow->next; // 慢指针移动一步
fast = fast->next->next; // 快指针移动两步
}
return true; // 当慢指针和快指针相遇,说明有环,返回 true
}
};
用到mergetwolists函数,其基本思想是让两个链表的头结点逐一比较大小,然后将较小的结点加入到一个新的链表中,直到其中一个链表为空(怎么感觉在耍赖 用这个函数ㄒoㄒ
class Solution {
public:
ListNode* mergeTwoLists(ListNode* l1, ListNode* l2) {
if (l1 == nullptr) {
return l2;
} else if (l2 == nullptr) {
return l1;
} else if (l1->val < l2->val) {
l1->next = mergeTwoLists(l1->next, l2);
return l1;
} else {
l2->next = mergeTwoLists(l1, l2->next);
return l2;
}
}
};