6.23算法日记
1.环形链表
解法
1.追击法
思路:
在一个环形的跑道上面,A和B从同一起点出发但是A的速度比B的速度快,那么久而久之A一定可以领先B一圈并且追上B的。
所以综上所述,在环形链表中定义两个指针分别为fastp和slowp,fastp每次向前走两个单位,而slowp每次向前走一个单位;如果链表不存在环形链表的话fastp.next是一定会为null的,反之存在环形链表的话fasp.next和fasp.next.next永远不会为null的,那么此时进入while循环分别将slowp和fastp向前移动一个单位和两个单位,一旦slowp和fastp处在了同一位置,那么就说明了链表存在环。
其实也可以将fastp和slowp每次移动的单位长度变的更长,但是这样会增加算法的复杂度。
var hasCycle = function(head) {
if(head == null) return false
//定义一个快指针和一个慢指针,fastp每次移动两个单位,slowp每次移动一个单位
let fastp = head
let slowp = head
while(fastp.next != null && fastp.next.next != null) {
fastp = fastp.next.next
slowp = slowp.next
if(fastp == slowp) {
return true
}
}
return false
};
2.环形链表2
解法
追击法
思路:
前半部分思路同上一题一样,但是当快慢指针第一次相遇之后需要将slowp慢指针置于head初始位置,然后只要当两指针速度不相同,那么二者的速度就变为相同,一旦二者第二次重合了就表明重合的点为环的第一个节点
var detectCycle = function(head) {
if(head == null) return null
let fastp = head
let slowp = head
let loopExist = false
while(fastp.next != null && fastp.next.next != null) {
fastp = fastp.next.next
slowp = slowp.next
//二者第一次相遇,说明出现了环就可以跳出循环了
if(fastp == slowp) {
loopExist = true
break
}
}
if(loopExist) {
slowp = head
while(fastp != slowp) {
slowp = slowp.next
fastp = fastp.next
}
//第二次相遇就是链表入环的第一个节点
return slowp
}
return null
};
3.相交链表

解法
1.双指针
思路:
定义两个指针p1和p2分别指向两链表的头结点,然后每次往后推进一个单位,直至p1或p2到了链表末尾null时,再将该指针放入另一链表的头部,比如p1指针先到“null结点”了那么就将p1此时指向B链表的头结点。依次类推最后当两指针指向同一结点时即为两链表的相交结点(如果是null结点说明两链表不相交)
var getIntersectionNode = function(headA, headB) {
if(headA == null || headB == null) return null
//双指针
let p1 = headA
let p2 = headB
while(p1 != p2) {
p1 = p1 == null ? headB : p1.next
p2 = p2 == null ? headA : p2.next
}
return p1
};
2.差值法
思路:
首先计算两个链表的长度,然后得出两个链表的长度差diff,让较长链表直接跳过diff个单位长度,较长从diff位置开始,较短链表从首位置开始,二者开始比较直到出现p1 == p2就说明该结点为相交结点,如果一直到null都没有出现p1 ==p2则说明两链表不相交
var getIntersectionNode = function(headA, headB) {
// if(headA == null || headB == null) return null
let l1 = 0, l2 = 0, diff = 0
let p1 = headA, p2 = headB
while(p1 != null) {
l1++
p1 = p1.next
}
while(p2 != null) {
l2++
p2 = p2.next
}
if(l1 > l2) {
p1 = headA
p2 = headB
diff = l1 - l2
} else {
p1 = headB
p2 = headA
diff = l2 - l1
}
for(let i = 0; i < diff; i++) {
p1 = p1.next
}
while(p1 != null && p2 != null) {
if(p1 == p2) {
return p1
}
p1 = p1.next
p2 = p2.next
}
return null
};