合并两个有序链表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 var mergeTwoLists = function (list1, list2 ) { let dummyHead = new ListNode(-1 ); let p1 = list1, p2 = list2; let p = dummyHead; while (p1 && p2) { if (p1.val > p2.val) { p.next = p2; p2 = p2.next; } else { p.next = p1; p1 = p1.next; } p = p.next; } p.next = p1 || p2; return dummyHead.next; };
链表中倒数第 K 个节点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 var getKthFromEnd = function (head, k ) { let slow, fast; slow = fast = head; for (let i = 0 ; i < k; i++) { fast = fast.next; } while (fast) { fast = fast.next; slow = slow.next; } return slow; };
删除链表的倒数第 N 个结点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 var removeNthFromEnd = function (head, n ) { const dummyHead = new ListNode(-1 , head); const temp = getKthFromEnd(dummyHead, n + 1 ); temp.next = temp.next.next; return dummyHead.next; function getKthFromEnd (head, k ) { let slow, fast; slow = fast = head; for (let i = 0 ; i < k; i++) { fast = fast.next; } while (fast) { fast = fast.next; slow = slow.next; } return slow; } };
链表的中间结点 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 var middleNode = function (head ) { let slow, fast; slow = fast = head; while (fast && fast.next) { fast = fast.next.next; slow = slow.next; } return slow; };
环形链表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 var hasCycle = function (head ) { let slow, fast; slow = fast = head; while (fast && fast.next) { fast = fast.next.next; slow = slow.next; if (fast === slow) { return true ; } } return false ; };
环形链表 II 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 var detectCycle = function (head ) { let slow, fast; slow = fast = head; let flag = false ; while (fast && fast.next) { slow = slow.next; fast = fast.next.next; if (slow === fast) { flag = true ; break ; } } if (!flag) { return null ; } slow = head; while (slow !== fast) { slow = slow.next; fast = fast.next; } return slow; };
相交链表 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 var getIntersectionNode = function (headA, headB ) { let p1 = headA, p2 = headB; while (p1 !== p2) { p1 = p1 ? p1.next : headB; p2 = p2 ? p2.next : headA; } return p1; };
反转链表 迭代版 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 var reverseList = function (head ) { let prev = null , cur = head; while (cur) { const tmp = cur.next; cur.next = prev; prev = cur; cur = tmp; } return prev; };
递归版 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 var reverseList = function (head ) { if (head === null || head.next === null ) { return head; } const newList = reverseList(head.next); const p2 = head.next; p2.next = head; head.next = null ; return newList; };
如果对 2->3->4 进行递归反转,则得到:
接下来只要把节点 2 的 next 指向节点 1,然后节点 1 的 next 指向 null 即可,如图:
反转链表 II 定义两个指针,分别称之为 g(guard 守卫) 和 p(point)。我们首先根据方法的参数 left 确定 g 和 p 的位置。将 g 移动到第一个要反转的节点的前面,将 p 移动到第一个要反转的节点的位置上。我们以 left = 2,right = 4 为例。 头插法:将 p 后面的元素删除,然后添加到 g 的后面。 重复上面头插法的步骤,一共需要操作 right - left 次。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 var reverseBetween = function (head, left, right ) { let dummyHead = new ListNode(-1 , head); let g = dummyHead, p = dummyHead.next; for (let i = 0 ; i < left - 1 ; i++) { g = g.next; p = p.next; } for (let i = 0 ; i < right - left; i++) { let removed = p.next; p.next = p.next.next; removed.next = g.next; g.next = removed; } return dummyHead.next; };
参考资料:
https://www.pianshen.com/article/1931399442/ https://labuladong.gitee.io/algo/2/16/15/ https://leetcode-cn.com/problems/reverse-linked-list-ii/solution/java-shuang-zhi-zhen-tou-cha-fa-by-mu-yi-cheng-zho/