牛客题目链接
1. 题目考点
- 归并排序
- merge 函数三种形式
- PriorityQueue
2. 考点解析
- 使用 ArrayList,排序再插入 (投机取巧,面试千万不可)
public ListNode mergeKLists(ArrayList<ListNode> lists) {
ArrayList<Integer> arr = new ArrayList<>();
for (int i = 0 ; i < lists.size(); i++) {
ListNode p = lists.get(i);
while (p != null) {
arr.add(p.val);
p = p.next;
}
}
arr.sort((a,b)-> a-b);
ListNode dummy = new ListNode(0), r = dummy;
for (int i = 0; i < arr.size(); i++) {
ListNode node = new ListNode(arr.get(i));
r.next = node;
r = node;
}
r.next = null;
return dummy.next;
}
- 使用小顶堆 PriorityQueue,其实类似第一种方式 (面试可行)
public ListNode mergeKLists(ArrayList<ListNode> lists) {
if (lists == null || lists.size() == 0) return null;
Queue<Integer> pq = new PriorityQueue<>();
for (ListNode node : lists) {
while (node != null) {
pq.offer(node.val);
node = node.next;
}
}
ListNode dummy = new ListNode(0);
ListNode r = dummy;
while (!pq.isEmpty()) {
ListNode node = new ListNode(pq.poll());
r.next = node;
r = node;
}
return dummy.next;
}
- 归并排序,先递归划分,在两两合并
public ListNode mergeKLists(ArrayList<ListNode> lists) {
if (lists.size() == 0) return null;
return mergeSort(lists, 0, lists.size() - 1);
}
public ListNode mergeSort(ArrayList<ListNode> lists, int l, int r) {
if (l == r) return lists.get(l);
int mid = l + ((r - l) >> 2);
ListNode l1 = mergeSort(lists, l, mid);
ListNode l2 = mergeSort(lists, mid + 1, r);
return merge(l1, l2);
}
public ListNode merge(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode r = dummy;
while (true) {
if (l1 == null) {
r.next = l2;
break;
} else if (l2 == null) {
r.next = l1;
break;
} else if (l1.val < l2.val) {
r.next = l1;
l1 = l1.next;
r = r.next;
} else {
r.next = l2;
l2 = l2.next;
r = r.next;
}
}
return dummy.next;
}
- merge 函数采用一般方式
public ListNode merge(ListNode l1, ListNode l2) {
ListNode dummy = new ListNode(0);
ListNode r = dummy;
while (l1 != null && l2 != null) {
if (l1.val < l2.val) {
r.next = l1;
l1 = l1.next;
} else {
r.next = l2;
l2 = l2.next;
}
r = r.next;
}
if (l1 != null) r.next = l1;
if (l2 != null) r.next = l2;
return dummy.next;
}
- merge 函数采用递归方式(不容易想到,本质是修改链)
public ListNode merge(ListNode l1, ListNode l2) {
if (l1 == null) return l2;
if (l2 == null) return l1;
if (l1.val < l2.val) {
l1.next = merge(l1.next, l2);
return l1;
}
else {
l2.next = merge(l1, l2.next);
return l2;
}
}