Find largest and second largest element in a range

后端 未结 11 1909
情歌与酒
情歌与酒 2020-12-10 07:30

How do I find the above without removing the largest element and searching again? Is there a more efficient way to do this? It does not matter if the these elements are dupl

相关标签:
11条回答
  • 2020-12-10 07:31
    for (e: all elements) {
     if (e > largest) {
       second = largest;
       largest = e;
     } else if (e > second) {
       second = e;
     }
    }
    

    You could either initialize largest and second to an appropriate lower bound, or to the first two items in the list (check which one is bigger, and don't forget to check if the list has at least two items)

    0 讨论(0)
  • 2020-12-10 07:34

    using partial_sort ?

    std::partial_sort(aTest.begin(), aTest.begin() + 2, aTest.end(), Functor);
    

    An Example:

    std::vector<int> aTest;
    
        aTest.push_back(3);
        aTest.push_back(2);
        aTest.push_back(4);
        aTest.push_back(1);
    
    
        std::partial_sort(aTest.begin(), aTest.begin()+2,aTest.end(), std::greater<int>());
    
        int Max = aTest[0];
    int SecMax = aTest[1];
    
    0 讨论(0)
  • 2020-12-10 07:35

    Create a sublist from n..m, sort it descending. Then grab the first two elements. Delete these elements from the orginal list.

    0 讨论(0)
  • 2020-12-10 07:39

    Untested but fun:

    template <typename T, int n>
    class top_n_functor : public unary_function<T, void>
    {
    
      void operator() (const T& x) {
         auto f = lower_bound(values_.begin(), values_.end(), x);
    
         if(values_.size() < n) {
             values_.insert(f, x);
             return;
         }
    
         if(values_.begin() == f)
              return;
    
         auto removed = values_.begin();
         values_.splice(removed, values_, removed+1, f);
    
         *removed = x;
      }
    
      std::list<T> values() {
         return values_;
      }
    private:
       std::list<T> values_;
    };
    
    int main()
    {
      int A[] = {1, 4, 2, 8, 5, 7};
      const int N = sizeof(A) / sizeof(int);
    
      auto vals = for_each(A, A + N, top_n_functor<int,2>()).values();
    
      cout << "The top is " << vals.front()
           << " with second place being " << *(vals.begin()+1) << endl;
    }
    
    0 讨论(0)
  • 2020-12-10 07:40

    The optimal algorithm shouldn't need more than 1.5 * N - 2 comparisons. (Once we've decided that it's O(n), what's the coefficient in front of N? 2 * N comparisons is less than optimal).

    So, first determine the "winner" and the "loser" in each pair - that's 0.5 * N comparisons.

    Then determine the largest element by comparing winners - that's another 0.5 * N - 1 comparisons.

    Then determine the second-largest element by comparing the loser of the pair where the largest element came from against the winners of all other pairs - another 0.5 * N - 1 comparisons.

    Total comparisons = 1.5 N - 2.

    0 讨论(0)
  • 2020-12-10 07:40

    The answer depends if you just want the values, or also iterators pointing at the values.

    Minor modification of @will answer.

    v::value_type second_best = 0, best = 0;
    for(v::const_iterator i=v.begin(); i!=v.end(); ++i)
    {
       if(*i > best)
       {
         second_best = best;
         best = *i;
       }
       else if (*i > second_best)
       {
         second_best = *i;
       }
    }
    
    0 讨论(0)
提交回复
热议问题