无序数组中求最大值和最小值的最少比较次数

本文探讨了在无序数组中寻找最大值和最小值的多种方法,包括使用排序算法、双指针法以及分治法等,重点分析了比较次数最少的策略,如通过两个值记录最大值和最小值,比较次数仅为1.5*N。文章还提供了不同方法的实现思路,并引用了相关参考资料。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

无序数组中求最大值和最小值的最少比较次数

原理介绍

求一个无序数组中的最大值和最小值是一个很常见的情况, 一般来说, 最大值和最小值不是同一个元素, 我们可以通过下面几种方法来求:

  1. 排序算法:将数组排序后, 第一个元素是最小值,最后一个元素是最大值,以快排平均复杂度为例,时间复杂度 O ( N l o g N ) O(NlogN) O(NlogN),空间复杂度: O ( l o g N ) O(logN) O(logN),比较次数: N l o g N NlogN NlogN ;
  2. 两个元素记录最大值和最小值,判断每个值是否大于最大值或者最小值, 比较次数: 2 ∗ N 2*N 2N';
  3. 使用两个值记录最大值和最小值, 每次取出两个值,先进行比较,小的与最小值比较,大的与最大值比较 , 比较次数: 1.5 ∗ N 1.5*N 1.5N
  4. 将相邻的数进行比较,大的放在偶数位置,小的放在奇数位置, 最后奇数位置比较和偶数位置对应比较,得到最大值和最小值,比较次数: 1.5 ∗ N 1.5*N 1.5N ;
  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 1.5*N 1.5N

// 找到数组元素的最大值和最小值 
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 1.5*N 1.5N

// 找到数组元素的最大值和最小值 
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. 【编程之美】读书笔记:寻找数组中的最大值和最小值
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值