简体   繁体   中英

details of finding 2nd smallest element in unsorted array

Let me make things clear: I want to know more about the implementation of the "best" ALGORITHM how to find 2nd smallest element in array, which is described here:

Algorithm: Find index of 2nd smallest element from an unknown array

First, I am completely clear about the ALGORITHM how to find 2nd smallest element in array. The best solution is O(n+lg(n)-2) which can be achieved by first obtaining the smallest element S and then searching the smallest element of S's competitors. Read here: Algorithm: Find index of 2nd smallest element from an unknown array

What I cannot understand is how to implement it.

Especially, after finding the smallest element, how to track back those competitors of the smallest element such that I can find 2nd smallest element in those competitors?


NO NEED TO SORT. Quicksort is O(nlg(n)) which is worse than O(n+lg(n)-2).

There have been too many people talking about the best solution while nobody actually gave an implementation. Besides, I found the best solution is just theoretical best. It is very hard to implement it following that "best" solution.

int smallest, secondsmallest;
if (array[0] < array[1]) {
    smallest = array[0];
    secondsmallest = array[1];
} else {
    smallest = array[1];
    secondsmallest = array[0];
}
for(int i = 2; i < array_size; i++) {
    if (array[i] < smallest) {
        secondsmallest = smallest;
        smallest = array[i];
    } else if (array[i] < secondsmallest) {
        secondsmallest = array[i];
    }
}

Odd that no one has bothered to give this its name. Including the original questioner. For those unfamiliar with it, it is called the i th order statistic, and is discussed in many fine algorithm books. It is indeed O(n) (actually theta of n) for n elements.

Try this, should work

min1 = a[0]; 
min2 = 0;
int i = 0;
for (i = 0; i < a.length; i++){
   if (min1 < a[i]){
      min2 = min1;
      min1 = a[i];
   }
}

a.length is a Java instance of array. I'm not sure if C++ has the same one.

// A simple implementation with O(n) runtime complexity;
int findSecondMin(vector<int>& nums) {
    if (nums.size() < 2) throw runtime_error("no second minimum !");
    int min1 = nums[0], min2 = INT_MAX;
    for(int i=1;i<nums.size();i++) {
      if (nums[i] < min1) {
        min2 = min1;
        min1 = nums[i];
      } else if (nums[i] < min2) {
        min2 = nums[i];
      }
    }
    return min2;
}

You should keep the running "candidates" (and maybe number of their occurrences, depending on your strict definition of "2nd") for the smallest and second smallest value all along the way.

Well, you kind of answered your own question:

  1. How do you keep track of the smallest element? You store an index to it.
  2. How do you find the second smallest element? Search again and ignore the element you found first.

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