無序數組中求最大值和最小值的最少比較次數


無序數組中求最大值和最小值的最少比較次數

無序數組中求最大值和最小值的最少比較次數

原理介紹

求一個無序數組中的最大值和最小值是一個很常見的情況, 一般來說, 最大值和最小值不是同一個元素, 我們可以通過下面幾種方法來求:

  1. 排序算法:將數組排序后, 第一個元素是最小值,最后一個元素是最大值,以快排平均復雜度為例,時間復雜度 $O(NlogN)$,空間復雜度: $O(logN)$,比較次數: $NlogN$ ;
  2. 兩個元素記錄最大值和最小值,判斷每個值是否大於最大值或者最小值, 比較次數: $2*N$';
  3. 使用兩個值記錄最大值和最小值, 每次取出兩個值,先進行比較,小的與最小值比較,大的與最大值比較 , 比較次數: $1.5*N$
  4. 將相鄰的數進行比較,大的放在偶數位置,小的放在奇數位置, 最后奇數位置比較和偶數位置對應比較,得到最大值和最小值,比較次數: $1.5*N$ ;
  5. 分治法, topK 問題的簡化版本分成兩部分,找到前半部分的 Min Max, 最后比較結果可得到最后的值

方法3 和方法4的 過程很接近, 方法3 更為容易實現, 具體實現可見后續

算法實現

方法1 快排

// 找到數組元素的最大值和最小值 
vector<int> findMinMax(vector<int> arr)
{
    sort(arr.begin(),arr.end());
    return {arr[0],arr.back()};
}

方法 2

// 找到數組元素的最大值和最小值 
vector<int> findMinMax(vector<int> arr)
{
    int min_ = INT_MAX,max_ = INT_MIN;
    for(int i=0;i<arr.size();++i)
    {
        if(arr[i] > max_)
            max_ = arr[i];
        if(arr[i] < min_)
            min_ = arr[i];
    }
    return {min_,max_};
}

方法 3

使用兩個值記錄最大值和最小值, 每次取出兩個值,先進行比較,小的與最小值比較,大的與最大值比較 , 比較次數: $1.5*N$

// 找到數組元素的最大值和最小值 
vector<int> findMinMax(vector<int> arr) {
    int min_ = INT_MAX,max_ = INT_MIN;
    // 處理前面偶數個元素
    for(int i=0;i<arr.size()/2;++i) {
        // 得到兩個元素的最大值和最小值
        int tmp_min,tmp_max;
        if(arr[i] < arr[i+1]) {
            tmp_min = arr[i];
            tmp_max = arr[i+1];
        } else {
            tmp_min = arr[i+1];
            tmp_max = arr[i];
        }
        // 比較,更新最大值和最小值
        if(tmp_max > max_)  max_ = tmp_max;
        if(tmp_min < min_)  min_ = tmp_min;
    }

    // 處理數組個數為奇數的情況 // 處理最后一個元素
    if(arr.size()%2) {
        int tmp = arr.back();
        if(tmp > max_)  max_ = tmp;
        if(tmp < min_)  min_ = tmp;
    }

    return {min_,max_};
}

方法 4

比較前面偶數個元素,小的放在奇數位置,大的放在偶數位置, 比較次數: $1.5*N$

// 找到數組元素的最大值和最小值 
vector<int> findMinMax(vector<int> arr) {
    int min_ = INT_MAX,max_ = INT_MIN;
    // 調整位置, 小的位於奇數,大的位置偶數
    for(int i=0;i<arr.size()/2;i++) {
        if(arr[i] > arr[i+1])   swap(arr[i],arr[i+1]);
    }
    // 更新最大值和最小值
    for(int i=0;i<arr.size()/2;i++) {
        if(arr[i] < min_)   min_ = arr[i];
        if(arr[i+1] > max_) max_ = arr[i+1];
    }

    // 處理數組個數為奇數的情況 // 處理最后一個元素
    if(arr.size()%2) {
        int tmp = arr.back();
        if(tmp > max_)  max_ = tmp;
        if(tmp < min_)  min_ = tmp;
    }

    return {min_,max_};
}

方法5

在N個數中求最小值Min和Max, 分成兩個部分,依次取Min和Max,

參考鏈接

  1. 關於在一個無序數組中的數求最大值和最小值的最小比較次數
  2. 無序數組同時查找最大和最小的元素
  3. 面試題-算法:亂序數組中找最大值和最小值
  4. 【編程之美】讀書筆記:尋找數組中的最大值和最小值


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM