/** * Definition for singly-linked list. * function ListNode(val, next) { * this.val = (val===undefined ? 0 : val) * this.next = (next===undefined ? null : next) * } */ /** * @param {ListNode[]} lists * @return {ListNode} */ const mergeKLists = function (lists) { }; function ListNode(val, next) { this.val = (val === undefined ? 0 : val); this.next = (next === undefined ? null : next); } /* 定义一个minIndex变量来记录当前最小头节点的索引。 在每次循环中,遍历lists数组,找到当前最小头节点的索引minIndex。 如果找到的minIndex为-1,说明没有更多的节点可以合并,跳出循环。 如果找到的minIndex不为-1,将当前最小头节点添加到合并后的链表中。 然后将lists[minIndex]指向下一个节点,继续下一轮循环。 */ /** * 合并k个升序链表 * @param {ListNode[]} lists * @return {ListNode} */ function f1(lists) { const dummy = new ListNode(0); let current = dummy; // 遍历lists,找到最小的头节点 while (true) { let minIndex = -1; for (let i = 0; i < lists.length; i++) { if (lists[i] && (minIndex === -1 || lists[i].val < lists[minIndex].val)) { minIndex = i; // 更新最小头节点的索引 } } if (minIndex === -1) break; // 没有找到最小的头节点 current.next = lists[minIndex]; // 拼接到dummy节点上 current = current.next; // 移动到下一个节点 lists[minIndex] = lists[minIndex].next; // 移动到下一个头节点 } return dummy.next; // 返回合并后的链表 } /* 定义一个ans表示要返回的链表,然后将lists中的链表挨个和它合并,最终返回ans */ function f2(lists) { let ans = null; for (let i = 0; i < lists.length; i++) { ans = mergeLists(ans, lists[i]); } return ans; } /* 使用分治法 */ function f3(lists) { return merge(lists, 0, lists.length - 1); } /** * @param {ListNode[]} lists 链表数组 * @param {number} l 要进行合并的左边界 * @param {number} r 要进行合并的右边界 * merge函数会将l到r范围的链表合并成一个新链表 */ function merge(lists, l, r) { // 如果l和r相等,表明这个范围只有一个链表,直接返回 if (l === r) return lists[l]; if (l > r) return null; // 将l到r的范围拆分成左右两部分,等这两部分merge之后再合并它们 const mid = Math.floor((l + r) / 2); return mergeLists(merge(lists, l, mid), merge(lists, mid + 1, r)); } function mergeLists(l1, l2) { if (l1 === null || l2 === null) { return l1 === null ? l2 : l1; } const dummy = new ListNode(0); let cur = dummy; while (l1 && l2) { if (l1.val <= l2.val) { cur.next = l1; l1 = l1.next; } else { cur.next = l2; l2 = l2.next; } cur = cur.next; // 移动到下一个节点 } cur.next = l1 === null ? l2 : l1; // 将剩余的节点拼接到链表后面 return dummy.next; // 返回合并后的链表 }