问题
合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。
示例
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
自解
思路
暴力法,通过count变量记录已经移动至尾部的链表数量,通过flag2数组标记已经移动至尾部的链表。比k 个节点(每个链表的首节点),获得最小值的节点。将获得的最小值放入有序链表的尾部。
代码
class Solution {
public int minIndex, min = Integer.MAX_VALUE;
//添加节点
public ListNode addListNode(ListNode root, int val) {
ListNode temp1 = root;
while (temp1.next != null)
temp1 = temp1.next;
ListNode temp2 = new ListNode(val);
temp1.next = temp2;
return root;
}
//输出链表
public void displayListNode(ListNode root) {
while (root.next != null) {
System.out.print(root.val + "->");
root = root.next;
}
System.out.println(root.val);
}
//找到数组中的最小值
public int findMin(int list[]) {
for (int i = 0; i < list.length; i++) {
if (list[i] <= min) {
min = list[i];
minIndex = i;
}
}
return min;
}
public ListNode mergeKLists(ListNode[] lists) {
boolean flag = false;
boolean flag2[] = new boolean[lists.length];
int count = 0;
if (lists.length == 0 || lists == null)
return null;
int temp[] = new int[lists.length];
for (int i = 0; i < lists.length; i++) {
flag2[i] = true;
if (lists[i] == null) {
temp[i] = Integer.MAX_VALUE;
count ++;
flag2[i] = false;
continue;
}
else {
temp[i] = lists[i].val;
flag = true;
}
}
if (flag == false)
return null;
findMin(temp);
ListNode ans = new ListNode(min);
if (lists[minIndex].next != null) {
lists[minIndex] = lists[minIndex].next;
}
else {
lists[minIndex].val = Integer.MAX_VALUE;
if (flag2[minIndex] == true)
{
count++;
flag2[minIndex] = false;
}
}
while (count < lists.length) {
boolean flag3 = false;
for (int i = 0; i < lists.length; i++) {
if (lists[i] == null) {
temp[i] = Integer.MAX_VALUE;
}
else {
temp[i] = lists[i].val;
flag3 = true;
}
}
min = Integer.MAX_VALUE;
findMin(temp);
if (lists[minIndex].next != null) {
lists[minIndex] = lists[minIndex].next;
}
else {
lists[minIndex].val = Integer.MAX_VALUE;
if (flag2[minIndex] == true) {
flag2[minIndex] = false;
count++;
}
}
addListNode(ans, min);
}
return ans;
}
}
结果
时间复杂度O(K2N),空间复杂度O(N)