描述 合并K分類列表 狀態(tài):
您有一系列
k
鏈接-列表lists
,每個鏈接-列表按升序排序。合并所有鏈接-列表為一個排序的鏈接-列出并返回。
例如:
Input: lists = [[1, 4, 5], [1, 3, 4], [2, 6]]
Output: [1, 1, 2, 3, 4, 4, 5, 6]
Explanation: The linked-lists are:
[
1->4->5,
1->3->4,
2->6
]
merging them into one sorted list:
1->1->2->3->4->4->5->6
起初這個問題有點讓我感到困惑,但是 NEETCODE 很有意義。
解決方案的方法是 合并排序算法 ,這是您從任何介紹性計算機科學(xué)課程中可能記得的最熟悉的算法之一。
現(xiàn)在,當(dāng)我們將數(shù)組作為輸入作為輸入時,我們通常會合并排序,我們將數(shù)組遞歸將數(shù)組分為左和右半,并繼續(xù)合并它們,直到整個數(shù)組對整個數(shù)組進行排序。這是我們熟悉的朋友在JavaScript中的樣子:
function mergeSort(arr) {
if (arr.length <= 1) {
return arr;
}
let left = arr.slice(0, Math.floor(arr.length / 2));
let right = arr.slice(Math.floor(arr.length / 2), arr.length);
mergeSort(left);
mergeSort(right);
merge(left, right, arr);
return arr;
}
function merge(left, right, arr) {
let index = 0;
while (left.length && right.length) {
if (left[0] < right[0]) {
arr[index++] = left.shift();
} else {
arr[index++] = right.shift();
}
}
while (left.length) {
arr[index++] = left.shift();
}
while (right.length) {
arr[index++] = right.shift();
}
}
但是,我們要使用的是 * merge
功能。
由于我們還使用鏈接列表,因此看起來會有所不同。使用TypeScript,看起來像這樣:
function merge(list1: ListNode | null, list2: ListNode | null) {
let result = new ListNode(0);
let currentNode = result;
while (list1 !== null && list2 !== null) {
if (list1.val < list2.val) {
currentNode.next = list1;
list1 = list1.next;
} else {
currentNode.next = list2;
list2 = list2.next;
}
currentNode = currentNode.next;
}
if (list1 !== null) {
currentNode.next = list1;
}
if (list2 !== null) {
currentNode.next = list2;
}
return result.next;
}
自從我們給予 k
排序列表,我們將合并列表對,并繼續(xù)合并 lists
大于1:
function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
if (lists === null || lists.length === 0) {
return null;
}
while (lists.length > 1) {
let mergedLists = [];
for (let i = 0; i < lists.length; i += 2) {
let list1 = lists[i];
let list2 = i + 1 < lists.length ? lists[i + 1] : null;
mergedLists.push(merge(list1, list2));
}
lists = mergedLists;
}
return lists[0];
};
筆記 |
---|
如果 list2 是 null (在長度的情況下 lists 甚至不是),合并 list1 和 list2 將是 list1 。 |
總體而言,解決方案看起來像這樣:文章來源:http://www.zghlxwxcb.cn/news/detail-851178.html
/**
* Definition for singly-linked list.
* class ListNode {
* val: number
* next: ListNode | null
* constructor(val?: number, next?: ListNode | null) {
* this.val = (val === undefined ? 0 : val)
* this.next = (next === undefined ? null : next)
* }
* }
*/
function mergeKLists(lists: Array<ListNode | null>): ListNode | null {
if (lists === null || lists.length === 0) {
return null;
}
while (lists.length > 1) {
let mergedLists = [];
for (let i = 0; i < lists.length; i += 2) {
let list1 = lists[i];
let list2 = i + 1 < lists.length ? lists[i + 1] : null;
mergedLists.push(merge(list1, list2));
}
lists = mergedLists;
}
return lists[0];
};
function merge(list1: ListNode | null, list2: ListNode | null) {
let result = new ListNode(0);
let currentNode = result;
while (list1 !== null && list2 !== null) {
if (list1.val < list2.val) {
currentNode.next = list1;
list1 = list1.next;
} else {
currentNode.next = list2;
list2 = list2.next;
}
currentNode = currentNode.next;
}
if (list1 !== null) {
currentNode.next = list1;
}
if (list2 !== null) {
currentNode.next = list2;
}
return result.next;
}
時間和空間復(fù)雜性
時間復(fù)雜性是o(n log k)o(n\ log\ k) - 也看 NEETCODE的解釋 - ,如果您記得合并排序功能的時間復(fù)雜性是o(n log n)o(n\ 日志\ n) :我們通過合并操作中的每個項目,但是由于每次輸入都會減半,我們會記錄NLOG\ n次。在這里類似,nn是指節(jié)點的數(shù)量,而kk是列表的數(shù)量。
空間復(fù)雜性是O(k)o(k) 當(dāng)我們保留臨時的時,kk是列表的數(shù)量 mergedLists
多變的。文章來源地址http://www.zghlxwxcb.cn/news/detail-851178.html
到了這里,關(guān)于LeetCode Meditations:合并 K 排序列表的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!