简体   繁体   中英

How to constantly find the two smallest values from two different lists?

I have two different lists that contain integers and I need to constantly find the two smallest values between these two lists; I should note that I do NOT want to merge these two lists together, since they are different types.

I would like to know if my approach is good or bad. If it is bad, please let me know how I can make it more efficient.

  • Constantly have both lists sorted by descending order, so the mins will be at the bottom

  • Find the two mins from list1 and compare it with the two mins from list2 and find the two mins out of those four values

  • Remove the two mins from the associate list(s), combine their values together (required) and add it to list2

I am essentially performing a portion of the Huffman code, where I want to have a list of the frequency of chars in descending order.

Finding a min in List can be done in linear time without any sorting. Sorting and finding the min every time will be O(m*nlgn) m being the number of iterations and n the size of the list) .

A better way would to use PriorityQueue (min-heap) where the min is always on the top of the heap instead of sorting on every iteration.

Using a min-heap is common in implementing Huffman codes and greedy algorithms in general.

Although this would definitely work, the task of keeping the lists sorted at all times should be a reason for concern:

  • If your lists allow random access (ie ArrayList s), then the process of deleting from them costs you O(n)
  • If your lists allow O(1) deletions (ie LinkedList s), then the process of finding the insertion spot is O(n)

That is on top of the initial sorting, which would cost you O(n*log 2 n). In other words, there is no advantage to sorting your lists in the first place: maintaining them would cost you O(n) per operation, so you might as well do linear searches.

In other words, the algorithm works, but it is inefficient. Instead of maintaining sorted lists, use containers that maintain minimum or maximum for you, and allow for fast insertions/deletions (eg PriorityQueue ).

Why don't you keep your min values in variables instead of keeping sorted lists?

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM