链表的双指针技巧 leetcode 141、142、160、19、876
1. 在调用 next 字段之前,始终检查节点是否为空。
获取空节点的下一个节点将导致空指针错误。例如,在我们运行 fast = fast.next.next 之前,需要检查 fast 和 fast.next 不为空。
2. 仔细定义循环的结束条件。
141. 环形链表
var hasCycle = function(head) {
if(!head || !head.next) return false;
let slow = head;
let fast = head.next;
while(slow != fast){
if(!fast || !fast.next) return false;
fast = fast.next.next;
slow = slow.next;
}
return true;
};
142. 环形链表 II
var detectCycle = function(head) { if (head === null) { return null; } let slow = head, fast = head; while (fast !== null) { slow = slow.next; if (fast.next !== null) { fast = fast.next.next; } else { return null; } if (fast === slow) { let ptr = head; while (ptr !== slow) { ptr = ptr.next; slow = slow.next; } return ptr; } } return null; };
160. 相交链表
var getIntersectionNode = function(headA, headB) { let pa = headA, pb = headB; while(pa !== pb){ pa = pa === null?headB:pa.next; pb = pb === null?headA:pb.next; } return pa; };
19. 删除链表的倒数第 N 个结点
var removeNthFromEnd = function(head, n) {
let dummyhead = new ListNode(0,head);
let fast = head;
let slow = dummyhead;
for(let i = 0; i < n; i++){
fast = fast.next;
}
while(fast != null){
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return dummyhead.next;
};
876. 链表的中间结点
var middleNode = function(head) {
let fast = head;
let slow = head;
while(fast != null && fast.next != null){
fast = fast.next.next;
slow = slow.next;
}
return slow;
};