005-023-Merge k sorted lists 归并K个有序的链表

来源:互联网 发布:vscode lua 编辑:程序博客网 时间:2024/06/07 07:47

      • Description
      • 分析
      • Code
        • 使用heap

Description

Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

分析

  归并多个排序的链表为一个有序链表。这是继merge two sorted list之后的一个扩展,早几天面试的时候面试官直接要我在电脑上OJ这题。

  对于两个已经排序的链表,我们知道最小值定在两个头节点,然后我们通过比较获得最小节点之后,移动指向最小节点的指针,那么下一个最小节点还是在两个头节点中。

image

  将k个已排序的链表归并为一个有序链表,关键就是在k个链表中找到最小的节点,然后移除该节点并将其插入到输出链表的尾部,继续查找下一个最小节点,直到k个链表都为空。那么如何寻找最小节点呢?k个链表都是为有序的链表,那么每个链表中的最小节点在链表的头节点,所有链表中的最小节点就在k个链表的头节点中找,当移除最小节点后,该链表会有一个新的头节点,最小值还是在k个链表的头节点中找。如此重复,直到k个链表都为空,我们就能得到一个排序的链表了。

  那么如何快速找到这个最小节点呢,寻找最小值,那用堆啊。建立一个初始大小为k的堆,将k个链表的头节点放入其中。接着从堆中取出最小节点,添加到输出链表尾部,再将该最小节点的下一个节点插入堆中,若下一个节点为空,则说明已经到达链表尾部,该链表已经无需再处理。重复上述过程,直至堆为空,k个有序链表就归并为一个有序链表了。

  数据结构采用PriorityQueue,为节点建立一个比较器。

  若节点总数为n,堆的大小为k,对堆的插入或取出操作需要O(logk),那么这个算法的时间复杂度为O(nlogk)。空间复杂度为O(k)。

Code

使用heap

/** * Definition for singly-linked list. * public class ListNode { *     int val; *     ListNode next; *     ListNode(int x) { val = x; } * } */public class Solution {    public class NodeCompare implements Comparator<ListNode>{        public int compare(ListNode n1,ListNode n2){            return n1.val-n2.val;        }    }    public ListNode mergeKLists(ListNode[] lists) {        int k=lists.length;//heap size        ListNode tmpHead=new ListNode(-1);//fake head        ListNode cur=tmpHead;//current pointer        if(k==0)return tmpHead.next;        if(k==1)return tmpHead.next=lists[0];        else{            PriorityQueue<ListNode> heap=new PriorityQueue<ListNode>(k,new NodeCompare());            // k size heap, natrual order, aka min heap             //initialize heap, the min node is in the head of all list            for(int i=0;i<k;i++){                if(lists[i]!=null){                    heap.offer(lists[i]);                }            }            //find min till empty            while(!heap.isEmpty()){                ListNode min=heap.poll();//find min node                cur.next=min;//append to the output list                cur=cur.next;//cur move a step                if(min.next!=null){//if this list is empty, move on                    heap.offer(min.next);//insert next node                }                //continue             }            return tmpHead.next;        }    }}

image

0 0
原创粉丝点击