image.png

知识回顾:

合并两个有序的链表

  1. public ListNode margeTwoList(ListNode node1, ListNode node2){
  2. ListNode node = new ListNode(-1);
  3. ListNode tmp = node;
  4. while(node1!=null && node2!=null){
  5. if(node1.val <= node2.val){
  6. tmp.next = node1;
  7. node1 = node1.next;
  8. }else{
  9. tmp.next = node2;
  10. node2 = node2.next;
  11. }
  12. tmp = tmp.next;
  13. }
  14. tmp.next = node1!=null?node1:node2;
  15. return node.next;
  16. }

解法一:遍历法

第一次从中取出两个链表合并,然后再依次取出一个链表进行合并

  1. import java.util.*;
  2. public class Solution {
  3. public ListNode mergeKLists(ArrayList<ListNode> lists) {
  4. int n = lists.size();
  5. if(n == 0)
  6. return null;
  7. if(n == 1)
  8. return lists.get(0);
  9. ListNode node = lists.get(0);
  10. for(int i = 1; i < n; i++){
  11. node = margeTwoList(lists.get(i),node);
  12. }
  13. return node;
  14. }
  15. public ListNode margeTwoList(ListNode node1, ListNode node2){
  16. ListNode node = new ListNode(-1);
  17. ListNode tmp = node;
  18. while(node1!=null && node2!=null){
  19. if(node1.val <= node2.val){
  20. tmp.next = node1;
  21. node1 = node1.next;
  22. }else{
  23. tmp.next = node2;
  24. node2 = node2.next;
  25. }
  26. tmp = tmp.next;
  27. }
  28. tmp.next = node1!=null?node1:node2;
  29. return node.next;
  30. }
  31. }

缺点

时间复杂度为 O(kN)

优化

分治: O(logkN)
image.png

  1. import java.util.*;
  2. public class Solution {
  3. public ListNode mergeKLists(ArrayList<ListNode> lists) {
  4. return merge(lists,0,lists.size()-1);
  5. }
  6. public ListNode merge(ArrayList<ListNode> lists, int l, int r){
  7. if(l == r)
  8. return lists.get(l);
  9. if(l > r){
  10. return null;
  11. }
  12. int mid = l + (r-l)/2;
  13. return mergeTwoList(merge(lists,l,mid),merge(lists,mid+1,r));
  14. }
  15. public ListNode mergeTwoList(ListNode node1, ListNode node2){
  16. ListNode node = new ListNode(-1);
  17. ListNode tmp = node;
  18. while(node1!=null && node2!=null){
  19. if(node1.val <= node2.val){
  20. tmp.next = node1;
  21. node1 = node1.next;
  22. }else{
  23. tmp.next = node2;
  24. node2 = node2.next;
  25. }
  26. tmp = tmp.next;
  27. }
  28. tmp.next = node1!=null?node1:node2;
  29. return node.next;
  30. }
  31. }

解法二: 使用优先队列(加强理解)

  1. import java.util.*;
  2. public class Solution {
  3. public ListNode mergeKLists(ArrayList<ListNode> lists) {
  4. Queue<ListNode> pq = new PriorityQueue<>((v1, v2) -> v1.val - v2.val);
  5. for (ListNode node: lists) {
  6. if (node != null) {
  7. pq.offer(node);
  8. }
  9. }
  10. ListNode dummyHead = new ListNode(0);
  11. ListNode tail = dummyHead;
  12. while (!pq.isEmpty()) {
  13. ListNode minNode = pq.poll();
  14. tail.next = minNode;
  15. tail = minNode;
  16. if (minNode.next != null) {
  17. pq.offer(minNode.next);
  18. }
  19. }
  20. return dummyHead.next;
  21. }
  22. }