链表 - 具体案例
一、环形链表【leetcode - 141】
给你一个链表的头节点 head ,判断链表中是否有环。
如果链表中存在环 ,则返回 true 。 否则,返回 false 。
思路一:【循环 + Set或者数组】
- 声明一个Set或者数组序列中;
- 循环链表的每一个节点,如果数组中没有该节点,则添加到序列中;如果数组中有该节点,表示链表中存在环,直接返回true;
- 循环结束后,直接返回false;
function hasCycle(head) {
let set = new Set();
let p1 = head;
while(p1) {
if(set.has(p1)) {
return true;
}
set.add(p1);
p1 = p1.next;
}
return false;
};
思路二:【快慢指针】
- 定义快慢两个指针
- 每次快指针走2步,慢指针走1步
- 循环链表,如果快慢指针相等,则是环形链表
- 如果循环完成后,快慢指针不相等,则不是环形链表
快慢指针起始位置相同
function hasCycle(head) {
let p1 = head;
let p2 = head;
while(p1 && p2 && p2.next) {
p1 = p1.next;
p2 = p2.next.next;
if(p1 === p2) {
return true;
}
}
return false;
};
快慢指针起始位置不同
function hasCycle(head) {
if(!head || !head.next) {
return false
}
let slow = head;
let fast = head.next;
while(slow !== fast) {
if(!fast || !fast.next) {
return false;
}
slow = slow.next;
fast = fast.next.next;
}
return true;
};