描述
合并 k 个排序链表,返回合并后的排序链表。
输入:
[
1->4->5,
1->3->4,
2->6
]
输出: 1->1->2->3->4->4->5->6
解题思路
1.将所有节点添加到数组中,对数组节点从小到大排序,依次取出每个节点串成链表。
// 时间复杂度:O(n*logn),空间复杂度:O(n)。
public ListNode mergeKLists(ListNode[] lists)
{
if (lists == null || lists.length == 0) return null;
List<ListNode> nodes = new ArrayList<ListNode>();
for (ListNode list : lists) {
while (list != null) {
nodes.add(list);
list = list.next;
}
}
nodes.sort((ListNode node1, ListNode node2) -> {
return node1.val - node2.val;
});
ListNode head = new ListNode(0);
ListNode cur = head;
for (ListNode node : nodes) {
cur = cur.next = node;
}
return head.next;
}
2.遍历取出链表数组第一个节点,取最小的节点,然后串起来。
// 时间复杂度:O(k*n)
public ListNode mergeKLists(ListNode[] lists)
{
if (lists == null || lists.length == 0) return null;
ListNode head = new ListNode(0);
ListNode cur = head;
while (true) {
int minIndex = -1;//记录最小值的索引
for (int i = 0; i < lists.length; i++) {
//某条链表已经取完
if (lists[i] == null) continue;
//比较小的赋值
if (minIndex == -1 || lists[i].val < lists[minIndex].val) {
minIndex = i;
}
}
//取出了链表数组所有的值
if (minIndex == -1) break;
//串起来节点
cur = cur.next = lists[minIndex];
//取出后下移
lists[minIndex] = lists[minIndex].next;
}
return head.next;
}
3.利用Java数据结构小顶堆。
// 时间复杂度:O(n*logk),空间复杂度:O(k)。
public ListNode mergeKLists(ListNode[] lists)
{
if (lists == null || lists.length == 0) return null;
ListNode head = new ListNode(0);
ListNode cur = head;
PriorityQueue<ListNode> queue = new PriorityQueue<>((ListNode node1, ListNode node2) -> {
return node1.val - node2.val;
});
for (ListNode list : lists) {
if (list == null) continue;
queue.offer(list);
}
while (!queue.isEmpty()) {
ListNode list = queue.poll();
cur = cur.next = list;
if (list.next != null) {
queue.offer(list.next);
}
}
return head.next;
}
4.分治策略,将链表两两合并成一条,最后第一条链表就是结果。
合并两条链表
a、迭代
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
//虚拟头结点
ListNode head;
//赋值头结点
if (l1.val <= l2.val) {
head = l1;
l1 = l1.next;
} else {
head = l2;
l2 = l2.next;
}
ListNode cur = head;
//串起来剩余节点
while (l1 != null && l2 != null) {
if (l1.val <= l2.val) {
cur = cur.next = l1;
l1 = l1.next;
} else {
cur = cur.next = l2;
l2 = l2.next;
}
}
//串完一个链表,剩下的链表直接串后面即可
if (l1 == null) {
cur.next = l2;
} else if (l2 == null) {
cur.next = l1;
}
return head;
}
b、递归
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
if (l1.val <= l2.val) {
l1.next = mergeTwoLists2(l1.next,l2);
return l1;
} else {
l2.next = mergeTwoLists2(l1,l2.next);
return l2;
}
}
分治代码
// 时间复杂度:O(n*logk)
public ListNode mergeKLists(ListNode[] lists)
{
if (lists == null || lists.length == 0) return null;
int step = 1;
while (step < lists.length) {
int nextStep = step << 1;// step*2
// 相邻2、4、8...
for (int i = 0; i+step < lists.length; i += nextStep) {
lists[i] = mergeTwoLists(lists[i], lists[i+step]);// 合并2条链表
}
step = nextStep;
}
return lists[0];
}
网友评论