优先队列详解 leetCode23 java解决

大把博客在公司电脑和ipad上,等时机到了上传,这段时间就这么写着吧

  开门见山,为啥要用这个队列。

  优先队列:自动从小到大排序,为什么???源码安排的明明白白,上马。。。

  offer()方法:增加元素

/**
     * Inserts the specified element into this priority queue.
     *
     * @return {@code true} (as specified by {@link Queue#offer})
     * @throws ClassCastException if the specified element cannot be
     *         compared with elements currently in this priority queue
     *         according to the priority queue's ordering
     * @throws NullPointerException if the specified element is null
     */
    public boolean offer(E e) {
        if (e == null)
            throw new NullPointerException();
        modCount++;
        int i = size;
        if (i >= queue.length)
            grow(i + 1);
        size = i + 1;
        if (i == 0)
            queue[0] = e;
        else
            siftUp(i, e);
        return true;
    }

 siftUp()比较并排序

/**
     * Inserts item x at position k, maintaining heap invariant by
     * promoting x up the tree until it is greater than or equal to
     * its parent, or is the root.
     *
     * To simplify and speed up coercions and comparisons. the
     * Comparable and Comparator versions are separated into different
     * methods that are otherwise identical. (Similarly for siftDown.)
     *
     * @param k the position to fill
     * @param x the item to insert
     */
    private void siftUp(int k, E x) {
        if (comparator != null)
            siftUpUsingComparator(k, x);
        else
            siftUpComparable(k, x);
    }

接下来的我不用多说了吧,嘻嘻。

 java5引入的这个东东,实现了Queue接口,追踪源码确实是起源自java1.5,然后属于java Collections Framework的成员

/**
 * <p>This class is a member of the
 * <a href="{@docRoot}/../technotes/guides/collections/index.html">
 * Java Collections Framework</a>.
 *
 * @since 1.5
 * @author Josh Bloch, Doug Lea
 * @param <E> the type of elements held in this collection
 */

  优先级队列的特点:还是追踪源码,从源码中一点点解释

  One:使用时的注意事项

/**
 * An unbounded priority {@linkplain Queue queue} based on a priority heap.
 * The elements of the priority queue are ordered according to their
 * {@linkplain Comparable natural ordering}, or by a {@link Comparator}
 * provided at queue construction time, depending on which constructor is
 * used.  A priority queue does not permit {@code null} elements.
 * A priority queue relying on natural ordering also does not permit
 * insertion of non-comparable objects (doing so may result in
 * {@code ClassCastException}).
*/

翻译结果

基于优先级堆的无界优先级{@linkplain Queue Queue}。
优先队列的元素按照它们的顺序排列
{@linkplain Comparable natural order},或者使用{@link Comparator}
在队列构建时提供,具体取决于使用哪个构造函数。
优先队列不允许{@code null}元素。
依赖于自然顺序的优先队列也不允许插入不可比较的对象(这样做可能会导致 {@code ClassCastException})。

  Two:对头结点的操作

 * <p>The <em>head</em> of this queue is the <em>least</em> element
 * with respect to the specified ordering.  If multiple elements are
 * tied for least value, the head is one of those elements -- ties are
 * broken arbitrarily.  The queue retrieval operations {@code poll},
 * {@code remove}, {@code peek}, and {@code element} access the
 * element at the head of the queue.

翻译结果:

该队列的<em>head</em>是相对于指定顺序的<em>least</em>元素。如果多个元素以最小值绑定,则head就是这些元素之一——绑定是任意断开的。队列检索操作{@code poll},
{@code remove}、{@code peek}和{@code element}访问队列头部的元素。

  Three:界限

 * <p>A priority queue is unbounded, but has an internal
 * <i>capacity</i> governing the size of an array used to store the
 * elements on the queue.  It is always at least as large as the queue
 * size.  As elements are added to a priority queue, its capacity
 * grows automatically.  The details of the growth policy are not
 * specified.

大致意思:

优先队列是无界的,但是有一个内部容量用来控制队列中用来存储元素数组的大小。
它的值总是总是至少和队列大小一样。(看到了哈,这个队列的内部数据结构是数组)
当元素被添加到队列的时候,队列的容量会随着自动增长。(等会通过源码来看为什么)
没有确定的增长策略(有点坑哈?好奇内部的实现)

  Four:关于优先级队列迭代器

 * <p>This class and its iterator implement all of the
 * <em>optional</em> methods of the {@link Collection} and {@link
 * Iterator} interfaces.  The Iterator provided in method {@link
 * #iterator()} is <em>not</em> guaranteed to traverse the elements of
 * the priority queue in any particular order. If you need ordered
 * traversal, consider using {@code Arrays.sort(pq.toArray())}.

六级分很低的翻译,凑合,凑合

这个优先级类和迭代器实现了Collection和Iterator接口中所有可以实现的方法。其中
迭代器方法并没有提供以任何特定顺序遍历优先级队列,如果要进行有序遍历则需要使用
Arrays.sort(PQ.toArray)方法

  Five:同步问题

<p><strong>Note that this implementation is not synchronized.</strong>
 * Multiple threads should not access a {@code PriorityQueue}
 * instance concurrently if any of the threads modifies the queue.
 * Instead, use the thread-safe {@link
 * java.util.concurrent.PriorityBlockingQueue} class.

(很明显优先级队列不是同步的,多个线程访问会引发线程安全问题)

不翻译了。。。。。
就是说不安全,如果想要使用安全的队列,就使用线程安全的阻塞优先队列,在多线程中,这种队列可以用开构造线程池的阻塞队列

  Six:你最关心的复杂度问题

 *<p>Implementation note: this implementation provides
 * O(log(n)) time for the enqueuing and dequeuing methods
 * ({@code offer}, {@code poll}, {@code remove()} and {@code add});
 * linear time for the {@code remove(Object)} and {@code contains(Object)}
 * methods; and constant time for the retrieval methods
 * ({@code peek}, {@code element}, and {@code size}).


菜鸟翻译:

这个实现类提供了出队列,进队列时间复杂度为O(log(n))的poll,offer,remove,add(关于其中的方法的运用,后面有机会提),
线性时间方法:offer(),contains()
常数时间方法:peek(),element(),size()

真的发现了新大陆,自己忽略了这么好用的东东

  LeetCode 23 题解

 

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

示例:

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

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/merge-k-sorted-lists
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

  解法:要我自己解肯定要用先合并两个,然后再依次合并两个,直到合并完,麻烦

  上牛逼网友代码

  

/**
 * Definition for singly-linked list.
 * public class ListNode {
 *     int val;
 *     ListNode next;
 *     ListNode(int x) { val = x; }
 * }
 */
class Solution {
    public ListNode mergeKLists(ListNode[] lists) {
       if(lists == null || lists.length < 0){
           return null;
       }
        //创建优先级队列
        PriorityQueue<Integer> queue = new PriorityQueue();
        //遍历并存储node
        for(ListNode node:lists){
            while(node != null){
                queue.add(node.val);
                node = node.next;
            }
        }
        ListNode res = new ListNode(0);
       
        ListNode tmp= res;
        while(!queue.isEmpty()){
            ListNode temp = new ListNode(queue.poll());
            tmp.next = temp;
            tmp = tmp.next;
        }
        return res.next;
    }
}

 

 

 

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值