function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
//合并两个有序链表
function mergeTwoLists(
list1: ListNode | null,
list2: ListNode | null
): ListNode | null {
// 都为空,则返回[]
if (list1 == null && list2 == null) {
return null;
}
//只有一个有数据,则返回有数据的链表
if (list1 == null || list2 == null) {
return list1 || list2;
}
if (list1.val < list2.val) {
list1.next = mergeTwoLists(list1.next, list2);
return list1;
} else {
list2.next = mergeTwoLists(list1, list2.next);
return list2;
}
}
/** 深度优先搜索算法 */
/** 分治算法 */
function dfs(i: number, j: number): ListNode | null {
const m = j - i;
// 数组为空,则返回
if (m === 0) return null;
//数组只有一个链表,直接返回
if (m === 1) return lists[i];
// >> 1 运算符 是将该值的二进制形式向右移动 1位,
// 奇数 = (该奇数 -1 /) 2 , 偶数 = 该偶数 / 2
// 奇数例: 5 >> 1 = (5 - 1) / 2 = 2;
// 偶数例:6 >> 1 = 6 / 2 = 3;
// 解释 left = dfs(i, i + (m >> 1))
// i: 始终取数据第0条数据 , i + (m >> 1):取剩下数组一半的数据,若数据为奇数,则先 -1变成偶数
// 例 [1,2,3,4,5] 索引 i:0, i + (m >> 1):2 就是取索引0 - 索引 1的,因为后面的2不包括在内
const left = dfs(i, i + (m >> 1));
// 解释 right = dfs(i + (m >> 1), j)
// i + (m >> 1):取剩下数组一半的数据,若数据为奇数,则先 -1变成偶数 j:整个数组的长度
// 例 [1,2,3,4,5] 索引 i + (m >> 1):2, j:5 就是取索引2 - 索引 4的,因为后面的5不包括在内
const right = dfs(i + (m >> 1), j);
//通过上面的操作,不断地将 数组一分为2,分完后,如果可以再分,则继续一分为2,直到无法再分了。
//通过递归,最终 left 与 right 分别为数组细分后的两个链表。再 通过 mergeTwoLists(left, right) 这个函数,将两个链表合并
// 最终一层一层返回到最初的链表数组上,所以最后该链表数组被分为了两个 合并后的链表,再将最后这两个链表合并,则全部合并完成
return mergeTwoLists(left, right);
}
return dfs(0, lists.length);
}
【leetCode 23】 合并 K 个升序链表(分治算法)
最新推荐文章于 2024-05-27 17:55:02 发布