如何从两个不同的列表中不断找到两个最小的值?

时间:2016-05-11 18:53:56

标签: java list min huffman-code

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

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

  • 不断有两个列表按降序排序,因此分钟将位于底部

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

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

我基本上是在执行霍夫曼代码的一部分,我希望按降序列出字符的频率列表。

3 个答案:

答案 0 :(得分:2)

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

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

使用min-heap在实施Huffman codes和贪婪算法时很常见。

答案 1 :(得分:1)

虽然这肯定会奏效,但始终保持列表排序的任务应该是值得关注的原因:

  • 如果您的列表允许随机访问(即ArrayList s),那么从中删除的过程将花费您O(n)
  • 如果您的列表允许O(1)删除(即LinkedList s),则查找插入点的过程为O(n)

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

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

答案 2 :(得分:0)

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

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);
}