3

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.

bob dylan
  • 647
  • 1
  • 10
  • 25

3 Answers3

2

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.

Sleiman Jneidi
  • 22,907
  • 14
  • 56
  • 77
  • I was thinking the same thing about that last night, but I (don't know why) still have trouble seeing out to actually use the priority queue. Like is the idea for the PQ this: find the two mins, create a new value with the sum of those two mins, add it to the PQ and then delete the old two mins/values? – bob dylan May 11 '16 at 19:07
  • @bobdylan exactly, you can poll from both queues, get the min of both elements and push to the min of both the queue again – Sleiman Jneidi May 11 '16 at 19:09
  • @bobdylan take good care to call pool on the PriorityQueue to get the element sorted don't rely on the iterator that is not sorted – Nicolas Filotto May 11 '16 at 19:35
1

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 (i.e. ArrayLists), then the process of deleting from them costs you O(n)
  • If your lists allow O(1) deletions (i.e. LinkedLists), 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*log2n). 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 (e.g. PriorityQueue).

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523
0

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);
}
shmosel
  • 49,289
  • 6
  • 73
  • 138