给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
思路:
每次选择链表数组中的最小值,直至所有节点均为空
实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ListNode dummyNode = new ListNode(-1);
ListNode cur = dummyNode;
while (true){
int index = -1;
int min = Integer.MAX_VALUE;
for(int i = 0; i < lists.length; i++){
if (lists[i] != null && lists[i].val < min){
index = i;
min = lists[i].val;
}
}
if (index == -1){
break;
}
cur.next = lists[index];
cur = cur.next;
lists[index] = lists[index].next;
}
return dummyNode.next;
}
}
思路:
使用小顶堆存放K个节点,每次弹出最小的节点
实现
/**
* Definition for singly-linked list.
* public class ListNode {
* int val;
* ListNode next;
* ListNode() {}
* ListNode(int val) { this.val = val; }
* ListNode(int val, ListNode next) { this.val = val; this.next = next; }
* }
*/
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
ListNode dummyNode = new ListNode(-1);
ListNode cur = dummyNode;
Queue<ListNode> pq = new PriorityQueue<>((v1, v2) -> v1.val - v2.val);
for (ListNode node :lists){
if (node != null){
pq.offer(node);
}
}
while (!pq.isEmpty()){
ListNode min = pq.poll();
if (min.next != null){
pq.add(min.next);
}
cur.next = min;
cur = cur.next;
}
return dummyNode.next;
}
}
复杂度
时间复杂度: O ( n l o g k ) O(nlogk) O(nlogk),K为数组的长度,n为链表的平均长度
空间复杂度: O ( k ) O(k) O(k)
思路:
对 K 条链表进行两两合并
递归实现
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) {
return null;
}
int k = lists.length;
while (k > 1) {
int idx = 0;
for (int i = 0; i < k; i += 2) {
if (i == k - 1) {
lists[idx++] = lists[i];
} else {
lists[idx++] = merge2Lists(lists[i], lists[i + 1]);
}
}
k = idx;
}
return lists[0];
}
private ListNode merge2Lists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
}
if (l2 == null) {
return l1;
}
if (l1.val < l2.val) {
l1.next = merge2Lists(l1.next, l2);
return l1;
}
l2.next = merge2Lists(l1, l2.next);
return l2;
}
}
作者:Sweetiee
链接:https://leetcode.cn/problems/merge-k-sorted-lists/solutions/220518/4-chong-fang-fa-xiang-jie-bi-xu-miao-dong-by-sweet/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度
时间复杂度: O ( n l o g k ) O(nlogk) O(nlogk),K为数组的长度,n为链表的平均长度
空间复杂度: O ( ) O() O()
迭代实现
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
if (lists.length == 0) {
return null;
}
return merge(lists, 0, lists.length - 1);
}
private ListNode merge(ListNode[] lists, int lo, int hi) {
if (lo == hi) {
return lists[lo];
}
int mid = lo + (hi - lo) / 2;
ListNode l1 = merge(lists, lo, mid);
ListNode l2 = merge(lists, mid + 1, hi);
return merge2Lists(l1, l2);
}
private ListNode merge2Lists(ListNode l1, ListNode l2) {
ListNode dummyHead = new ListNode(0);
ListNode tail = dummyHead;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
tail.next = l1;
l1 = l1.next;
} else {
tail.next = l2;
l2 = l2.next;
}
tail = tail.next;
}
tail.next = l1 == null? l2: l1;
return dummyHead.next;
}
}
作者:Sweetiee
链接:https://leetcode.cn/problems/merge-k-sorted-lists/solutions/220518/4-chong-fang-fa-xiang-jie-bi-xu-miao-dong-by-sweet/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
复杂度
时间复杂度: O ( n l o g k ) O(nlogk) O(nlogk),K为数组的长度,n为链表的平均长度
空间复杂度: O ( 1 ) O(1) O(1)