返回
探索 LeetCode 141 的解题思路,轻松理解环形链表的判断方法
见解分享
2023-12-03 07:10:51
- 快慢指针法:
快慢指针法是一种经典的算法,它通过使用两个指针来判断链表中是否存在环。具体做法是:
- 定义两个指针,一个称为慢指针,另一个称为快指针。
- 将慢指针和快指针都指向链表的头部。
- 让慢指针每次前进一步,而让快指针每次前进两步。
- 如果链表中存在环,那么快指针最终会追上慢指针。
这种方法的时间复杂度为 O(n),其中 n 是链表的长度。空间复杂度为 O(1),因为我们只使用了两个指针。
2. 散列表法:
散列表法也是一种常见的算法,它通过使用散列表来判断链表中是否存在环。具体做法是:
- 定义一个散列表,并将其初始化为空。
- 将链表的头部节点作为键值存入散列表。
- 让指针沿着链表向前移动,并将每个节点作为键值存入散列表。
- 如果检测到当前节点指针已经存在于散列表中,则说明链表中存在环。
这种方法的时间复杂度为 O(n),其中 n 是链表的长度。空间复杂度为 O(n),因为我们需要使用散列表来存储链表的节点。
3. 优缺点分析:
快慢指针法 :
- 优点:时间复杂度为 O(n),空间复杂度为 O(1)。
- 缺点:需要修改链表的结构,因为需要在每个节点中存储指向下一个节点的指针。
散列表法 :
- 优点:不需要修改链表的结构,因为不需要在每个节点中存储指向下一个节点的指针。
- 缺点:时间复杂度为 O(n),空间复杂度为 O(n)。
4. 代码示例:
快慢指针法 :
bool hasCycle(ListNode *head) {
if (head == NULL || head->next == NULL) {
return false;
}
ListNode *slow = head;
ListNode *fast = head->next;
while (slow != fast) {
if (fast == NULL || fast->next == NULL) {
return false;
}
slow = slow->next;
fast = fast->next->next;
}
return true;
}
散列表法 :
bool hasCycle(ListNode *head) {
unordered_map<ListNode *, bool> visited;
ListNode *current = head;
while (current != NULL) {
if (visited.find(current) != visited.end()) {
return true;
}
visited[current] = true;
current = current->next;
}
return false;
}
5. 结语:
通过对两种方法的分析和代码示例的讲解,我们对环形链表的判断方法有了更深入的理解。快慢指针法和散列表法都是有效的环形链表判断算法,您可以根据具体情况选择合适的方法进行应用。