平衡二叉树好像有点难,我来写个简单的摸摸鱼(
环形链表问题
Leetcode上有这样一道题
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中有某个节点,可以通过连续跟踪 next 指针再次到达,则链表中存在环。 为了表示给定链表中的环,评测系统内部使用整数 pos 来表示链表尾连接到链表中的位置(索引从 0 开始)。注意:pos 不作为参数进行传递 。仅仅是为了标识链表的实际情况。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
只让判断是否有环,非常简单,根据之前的备忘录算法我很快写出了这串代码:
class Solution {
public:
bool hasCycle(ListNode* head)
{
if(!head) return false;
std::unordered_map<ListNode*,int> mem;
while(head->next != nullptr)
{
if(mem.find(head) != mem.end()) return true;
mem.insert(std::pair<ListNode*,int>(head,head->val));
head = head->next;
}
return false;
}
};
非常优雅,但…
可以说是惨不忍睹了,虽知哈希表以空间换时间,但全盘皆输,着实令人大跌眼镜。
快慢指针算法
又叫Floyd判圈法(弗洛伊德判圈法),简单地说就是在表的头部放置两个前进速度不同的指针,使他们同时出发,如果该表不是线性表,则前进速度快的指针会率先进入”循环圈“,慢指针紧随其后,使快指针追击慢指针。由于有速度差异,只要该”循环圈“存在,快指针在”循环圈“内运行若干周期后,总会追上慢指针,所以只要指针和慢指针相遇,我们就能认定该链表是环形链表。
基于以上理解,我们可以写出如下代码:
class Solution {
public:
bool hasCycle(ListNode* head)
{
if(!head) return false;
int count = 2;
ListNode* slow = head;
while(head->next)
{
if(count == 0)
{
count = 2;
slow = slow->next;
}
else
{
--count;
head = head->next;
}
if(slow == head) return true;
}
return false;
}
};
效果立竿见影