一文搞懂单链表的六大解题套路 https://labuladong.gitee.io/algo/2/17/16/

21.合并两个有序链表(简单)
23.合并K个升序链表(困难)
141.环形链表(简单)
142.环形链表 II(中等)
876.链表的中间结点(简单)
160.相交链表(简单)
19.删除链表的倒数第 N 个结点(中等)


合并两个有序链表

image.png

动图:https://labuladong.gitee.io/algo/images/%e9%93%be%e8%a1%a8%e6%8a%80%e5%b7%a7/1.gif

  1. var mergeTwoLists = function(l1, l2) {
  2. const prehead = new ListNode(-1);
  3. let prev = prehead;
  4. while (l1 != null && l2 != null) {
  5. if (l1.val <= l2.val) {
  6. prev.next = l1;
  7. l1 = l1.next;
  8. } else {
  9. prev.next = l2;
  10. l2 = l2.next;
  11. }
  12. prev = prev.next;
  13. }
  14. // 合并后 l1 和 l2 最多只有一个还未被合并完,我们直接将链表末尾指向未合并完的链表即可
  15. prev.next = l1 === null ? l2 : l1;
  16. return prehead.next;
  17. };

引申-递归写法

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 个有序链表

image.png

最大堆(优先队列)

环形链表

快慢指针

/**
 * 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 个结点

image.png
image.png

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;
};

相交链表

链表问题 - 图5
双指针

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;
};