1. 找到环形链表的起始点
给定一个链表,返回链表开始入环的第一个节点。 如果链表无环,则返回
null
。 --引自力扣 #### 环形链表 II
1.2 利用快慢指针
解题思路:也是一样先把这个转成走格子的游戏,假设小A同学走到起始点需要走a步,此时小B同学走了2a+1,距离起始点a+1步。假设小A同学走到x的位置与小B同学相遇,则x-a = 2(x -1) + 1; x = a - 1,也就是说小A同学如果走到相遇的地方则需要走a-1步,距离起始点是a+1步。
相遇后让小B同学往前多走一步,则距离起始点a步,再将小A同学放到第一个格子前,小A同学距离起始点也是a步,然后小A同学和小B每次都向前走一步,他们相遇的地方就是环的起始点。
代码实现如下:
function ListNode(val) {
this.val = val;
this.next = null;
}
/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
if (!head) return null;
if (!head.next) return null;
if (!head.next.next) return null;
let p = head;
let q = head.next.next
while(q && q.next && q !== p) {
p = p.next;
q = q.next.next;
}
if (!q || !q.next) {
return null;
}
q = q.next.next;
p = head;
while(q !== p) {
q = q.next;
p = p.next;
}
return q;
};
1.2 利用数组和Set实现
解题思路:这个其实就是将所有的链表节点存放在数组或者Set当中,然后判断是否重复出现,而第一次出现的重复节点就是起始点。先遍历链表,然后判断数组或者Set当中是否存在相同的节点,如果是则是则返回当前节点。
代码实现如下
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {ListNode}
*/
var detectCycle = function(head) {
const set = new Set();
let curNode = head;
while(curNode) {
if (set.has(curNode)) {
return curNode;
}
set.add(curNode);
curNode = curNode.next;
}
return null;
};