(4)睡前刷一题,大厂不是梦!

337 阅读2分钟

今天分享的题目虽然是LeetCode hard 难度但是如果你看过一遍 他就变中等了,如果你实现两遍,它就变简单了。面试再也不怕这道高频题了。真希望遇到所有的hard题目都跟这题一样。

23. 合并K个排序链表

合并 k 个排序链表,返回合并后的排序链表。请分析和描述算法的复杂度。

示例:

输入: [ 1->4->5, 1->3->4, 2->6 ]

思路 :

  1. 每次遍历找出所有元素中最小的元素 ,可以使用使用hash结构快速获得某个链表的头部节点
  2. 创建一个大小固定的队列,将每个头结点放入到队列中,不断从队列中获取最小的元素,转换一下这不是就是最大堆。让出队元素的下一个元素添加进入最大堆中。
  3. 合并k个排序列表跟合并两个链表没有本质区别,只不过链表数量变多,借鉴归并排序的思想,不断合并两个有序列表

方法1

省略

方法2——最大堆

class Solution {
     public ListNode mergeKLists(ListNode[] lists) {
        PriorityQueue<ListNode> queue=new PriorityQueue<>(new Comparator<ListNode>() {
            @Override
            public int compare(ListNode o1, ListNode o2) {
                return o1.val-o2.val;
            }
        });
        for(int i=0;i<lists.length;i++){
            if(lists[i]==null){
                continue;
            }
            queue.add(lists[i]);
        }
        ListNode head=new ListNode(0);
        ListNode res=head;
        while(!queue.isEmpty()){
            ListNode out=queue.poll();
            if(out.next!=null){
                queue.add(out.next);
            }
            head.next=out;
            head=out;
        }
        return res.next;
    }
}

对于java8 可以在比较器部分进行部分代码优化

如:

Queue<ListNode> heap = new PriorityQueue((l1, l2) -> l1.val - l2.val);

方法3——分治思想

class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
       if(lists==null||lists.length==0){
           return null;
       }
       return merge(lists,0,lists.length-1);
    }
    private ListNode merge(ListNode[]lists,int left,int right){
        if(left==right){
            return lists[left];
        }
        int mid=left+(right-left)/2;
        ListNode l1=merge(lists,left,mid);
        ListNode l2=merge(lists,mid+1,right);
        return mergeTwoLists(l1,l2);
    }
    private ListNode mergeTwoLists(ListNode l1,ListNode l2){
        if(l1==null){
            return l2;
        }
        if(l2==null){
            return l1;
        }
        if(l1.val<l2.val){
            l1.next=mergeTwoLists(l1.next,l2);
            return l1;
        }
        else{
            l2.next=mergeTwoLists(l1,l2.next);
            return l2;
        }
    }
}