合并两个有序链表
将两个升序链表合并为一个新的 升序 链表并返回。新链表是通过拼接给定的两个链表的所有节点组成的。
示例 1:
输入:l1 = [1,2,4], l2 = [1,3,4]
输出:[1,1,2,3,4,4]
示例 2:
输入:l1 = [], l2 = []
输出:[]
示例 3:
输入:l1 = [], l2 = [0]
输出:[0]
迭代法
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0, l1);
ListNode cur = dummy;
while (l1 != null && l2 != null) {
if (l1.val > l2.val) {
cur.next = l2;
l2 = l2.next;
} else {
cur.next = l1;
l1 = l1.next;
}
cur = cur.next;
}
cur.next = l1 == null ? l2 : l1;
return dummy.next;
}
}
递归法
class Solution {
public ListNode mergeTwoLists(ListNode l1, ListNode l2) {
if (l1 == null) {
return l2;
} else if (l2 == null) {
return l1;
} else if (l1.val < l2.val) {
l1.next = mergeTwoLists(l1.next, l2);
return l1;
} else {
l2.next = mergeTwoLists(l1, l2.next);
return l2;
}
}
}
合并K个升序链表
给你一个链表数组,每个链表都已经按升序排列。
请你将所有链表合并到一个升序链表中,返回合并后的链表。
示例 1:
输入:lists = [[1,4,5],[1,3,4],[2,6]]
输出:[1,1,2,3,4,4,5,6]
解释:链表数组如下:
[
1->4->5,
1->3->4,
2->6
]
将它们合并到一个有序链表中得到。
1->1->2->3->4->4->5->6
示例 2:
输入:lists = []
输出:[]
示例 3:
输入:lists = [[]]
输出:[]
纵向遍历
依次合并两个链表
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int len = lists.length;
if (len < 1)
return null;
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
int count = 0;
while (len != 0) {
int j = 0;
for (int i = 0; i < len; i++) {
if (lists[i] != null) {
lists[j++] = lists[i];
}
}
if (j == 0)
break;
len = j;
int min_index = 0;
int min = Integer.MAX_VALUE;
for (int i = 0; i < len; i++) {
if (lists[i].val <= min) {
min_index = i;
min = lists[i].val;
}
}
cur.next = lists[min_index];
lists[min_index] = lists[min_index].next;
cur = cur.next;
}
return dummy.next;
}
}
分治合并
用分治的方法合并链表,可以先合并短的链表,再合并长的链表。
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
return merge(lists, 0, lists.length - 1);
}
private ListNode merge(ListNode[] lists, int l, int r) {
if (l == r) {
return lists[l];
}
if (l > r) {
return null;
}
int mid = (l + r) >> 1;
return mergeTwoLists(merge(lists, l, mid), merge(lists, mid + 1, r));
}
private ListNode mergeTwoLists(ListNode a, ListNode b) {
if (a == null || b == null)
return (a != null) ? a : b;
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while (a != null && b != null) {
if (a.val < b.val) {
cur.next = a;
a = a.next;
} else {
cur.next = b;
b = b.next;
}
cur = cur.next;
}
cur.next = (a != null) ? a : b;
return dummy.next;
}
}
横向遍历
链表两两合并
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
int len = lists.length;
if (len < 1)
return null;
ListNode head = null;
for (ListNode node: lists) {
head = mergeTwoList(head, node);
}
return head;
}
private ListNode mergeTwoList(ListNode a, ListNode b) {
if (a == null || b == null)
return (a != null) ? a : b;
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while (a != null && b != null) {
if (a.val < b.val) {
cur.next = a;
a = a.next;
} else {
cur.next = b;
b = b.next;
}
cur = cur.next;
}
cur.next = (a != null) ? a : b;
return dummy.next;
}
}
优先队列
使用优先队列对结点进行排序,每次选取最小的结点合并到结果链表中。
class Solution {
public ListNode mergeKLists(ListNode[] lists) {
PriorityQueue<ListNode> queue = new PriorityQueue<ListNode>((x,y)->x.val-y.val);
for (ListNode node: lists) {
if (node != null)
queue.offer(node);
}
ListNode dummy = new ListNode(0);
ListNode cur = dummy;
while (!queue.isEmpty()) {
cur.next = queue.poll();
cur = cur.next;
if (cur.next != null) {
queue.offer(cur.next);
}
}
return dummy.next;
}
}