一文搞懂单链表的六大解题套路 https://labuladong.gitee.io/algo/2/17/16/
21.合并两个有序链表(简单)
23.合并K个升序链表(困难)
141.环形链表(简单)
142.环形链表 II(中等)
876.链表的中间结点(简单)
160.相交链表(简单)
19.删除链表的倒数第 N 个结点(中等)
合并两个有序链表

动图:https://labuladong.gitee.io/algo/images/%e9%93%be%e8%a1%a8%e6%8a%80%e5%b7%a7/1.gif
var mergeTwoLists = function(l1, l2) {const prehead = new ListNode(-1);let prev = prehead;while (l1 != null && l2 != null) {if (l1.val <= l2.val) {prev.next = l1;l1 = l1.next;} else {prev.next = l2;l2 = l2.next;}prev = prev.next;}// 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可prev.next = l1 === null ? l2 : l1;return prehead.next;};
引申-递归写法
var mergeTwoLists = function(l1, l2) {
if (l1 === null) {
return l2;
} else if (l2 === null) {
return l1;
} else if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
};
<= 或 < 都可以
合并 k 个有序链表

环形链表
快慢指针
/**
* Definition for singly-linked list.
* function ListNode(val) {
* this.val = val;
* this.next = null;
* }
*/
/**
* @param {ListNode} head
* @return {boolean}
*/
var hasCycle = function (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;
};
删除链表的倒数第 N 个结点


var removeNthFromEnd = function(head, n) {
let fast = head, slow = head;
// p1 先走 k 步
for(let i = 0; i < n; i++) {
fast = fast.next;
}
if(!fast)
return head.next; // 处理 n等于链表长度的异常。
while(fast.next != null) {
fast = fast.next;
slow = slow.next;
}
slow.next = slow.next.next;
return head;
};
相交链表

双指针
var getIntersectionNode = function(headA, headB) {
if (headA === null || headB === null) {
return null;
}
let pA = headA, pB = headB;
while (pA !== pB) {
pA = pA === null ? headB : pA.next;
pB = pB === null ? headA : pB.next;
}
return pA;
};
