【问题标题】:How to constantly find the two smallest values from two different lists?如何不断地从两个不同的列表中找到两个最小值?
【发布时间】:2016-09-07 08:31:45
【问题描述】:

我有两个包含整数的不同列表,我需要不断地找到这两个列表之间的两个最小值;我应该注意,我不想将这两个列表合并在一起,因为它们是不同的类型。

我想知道我的方法是好是坏。如果不好,请告诉我如何提高效率。

  • 始终让两个列表按降序排序,因此分钟将位于底部

  • 从 list1 中找出两个分钟,并将其与 list2 中的两个分钟进行比较,然后从这四个值中找出两个分钟

  • 从关联列表中删除两分钟,将它们的值组合在一起(必需)并将其添加到 list2

我实际上是在执行 Huffman 代码的一部分,我想在其中得到一个按降序排列的字符频率列表。

【问题讨论】:

  • 不断地是什么意思?列表是否会随着时间而变化?
  • 为什么不在更新列表之前进行比较?
  • 方法似乎没问题...你试过了吗?您是否遇到任何性能问题?
  • 我还没有完全实现这个,在我继续之前想问一下。我想要不断地对列表进行排序的原因是,我可以始终准确地知道两个列表的分钟在哪里。
  • 最小堆对于您的列表可能是一个不错的选择

标签: java list min huffman-code


【解决方案1】:

List 中查找最小值可以在线性时间内完成,无需任何排序。每次排序并找到最小值将是O(m*nlgn)m 是迭代次数,n 是列表的大小)。

更好的方法是使用PriorityQueue (min-heap),其中 min 始终位于堆的顶部,而不是在每次迭代时进行排序。

使用min-heap 在实现Huffman codes 和一般的贪心算法中很常见。

【讨论】:

  • 昨晚我也在想同样的事情,但我(不知道为什么)仍然无法确定实际使用优先级队列。就像 PQ 的想法是这样的:找到两个分钟,用这两个分钟的总和创建一个新值,将其添加到 PQ,然后删除旧的两个分钟/值?
  • @bobdylan 确切地说,您可以从两个队列中轮询,获取两个元素的最小值并再次推送到两个队列的最小值
  • @bobdylan 小心调用 PriorityQueue 上的 pool 以使元素排序 不要依赖未排序的迭代器
【解决方案2】:

虽然这肯定行得通,但始终保持列表排序的任务应该引起关注:

  • 如果您的列表允许随机访问(即ArrayLists),那么从它们中删除的过程会花费您 O(n)
  • 如果您的列表允许 O(1) 次删除(即 LinkedLists),那么查找插入点的过程是 O(n)

这是在初始排序之上,这将花费您 O(n*log2n)。换句话说,首先对列表进行排序没有任何好处:维护它们每次操作都会花费您 O(n),因此您不妨进行线性搜索。

换句话说,该算法有效,但效率低下。不要维护排序列表,而是使用为您维护最小值或最大值的容器,并允许快速插入/删除(例如PriorityQueue)。

【讨论】:

    【解决方案3】:

    为什么不将最小值保存在变量中,而不是保存排序列表?

    List<Integer> list1, list2;
    int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
    
    void setMin(int newValue) {
        if (newValue < min1) {
            min1 = newValue;
        } else if (newValue < min2) {
            min2 = newValue;
        }
    }
    
    void updateList1(int newValue) {
        setMin(newValue);
        list1.add(newValue);
    }
    
    void updateList2(int newValue) {
        setMin(newValue);
        list2.add(newValue);
    }
    

    【讨论】:

    • 当你从列表中删除一个元素时会发生什么?
    • @SleimanJneidi,OP 没有提到这种可能性。但我想这会取消这个解决方案的资格。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-04-19
    • 2021-01-25
    • 1970-01-01
    • 2021-06-21
    • 1970-01-01
    • 1970-01-01
    • 2015-12-24
    相关资源
    最近更新 更多