Leetcode -- Merge k Sorted Lists

来源:互联网 发布:淘宝樊小林捕鼠 编辑:程序博客网 时间:2024/06/05 05:02

问题链接:https://oj.leetcode.com/problems/merge-k-sorted-lists/

问题描述:Merge k sorted linked lists and return it as one sorted list. Analyze and describe its complexity.

问题API:public ListNode mergeKLists(List<ListNode> lists)

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) {
 *         val = x;
 *         next = null;
 *     }
 * }
 */


问题分析:本题其实是一个很经典的k-sort题目,不管是linkedlist还是arraylist,其实本质上都是利用priority queue来处理的例子。leetcode之所以用linkedlist应该是方便我们处理而已,因为如果是arraylist需要处理的还有index。也无法好好地连接起来。

priority_queue本质上就是最小堆,也就是推进去的所有元素,每次pop出来都是最小值,所以首先List中所有的首元素也就是head node都push进priority queue里。

然后循环执行以下的过程:

1. 从priority_queue中pop出队列里的最小值对应的node。然后将这个node连接进结果list里

2.如果这个node之后还有node,就offer进队列里。

直到队列为空的时候,结果链表就构建完成了。

值得注意的是,如果需要利用到PriorityQueue<T> 容易,放进去的类需要实现以下两个东西之一:

1. Comparable接口。(override public int compareTo(T t))

2. Comparator接口。 (override public int compares(T t1, T t2))

下面是实现了Comparable接口的做法:

class Node implements Comparable<Node>{        ListNode curNode;    public Node(ListNode curNode){        this.curNode = curNode;    }        @Override    public int compareTo(Node node){        return (new Integer(this.curNode.val)).compareTo(new Integer(node.curNode.val));    }} public class Solution {    public ListNode mergeKLists(List<ListNode> lists) {        Queue<Node> node_queue = new PriorityQueue<Node>();        ListNode head = null, tmp = null;        for(ListNode ln : lists){            if(ln != null){                Node node = new Node(ln);                node_queue.offer(node);            }        }        while(!node_queue.isEmpty()){            Node n = node_queue.poll();            if(head == null){                head = n.curNode;                tmp = head;            }else{                tmp.next = n.curNode;                tmp = tmp.next;            }            if(tmp.next != null){                node_queue.offer(new Node(tmp.next));            }        }        return head;    }

上面的类定义的有点冗余,大家可以想想如何简化

另外下面给出的是实现Comparator的代码,实际上是一样的:

    public ListNode mergeKLists(List<ListNode> lists) {        if(lists == null || lists.size() == 0)            return null;        PriorityQueue<ListNode> k_queue = new PriorityQueue<ListNode>(lists.size(), new NodeComparator());        for(int i = 0; i < lists.size(); i++){            if(lists.get(i) != null)              k_queue.add(lists.get(i));        }        ListNode tmp = null, head = null;        while(!k_queue.isEmpty()){            ListNode tmp_node = k_queue.poll();            if(tmp_node.next != null)                k_queue.add(tmp_node.next);            if(head == null){                head = tmp = tmp_node;            }else{                tmp.next = tmp_node;                tmp = tmp.next;            }        }        return head;    }        class NodeComparator implements Comparator<ListNode>{        @Override        public int compare(ListNode n1, ListNode n2){            if(n1.val < n2.val)                return -1;            else if(n1.val == n2.val)                return 0;            else                return 1;        }    }


0 0
原创粉丝点击