【算法】16个无序数最多20次比较找到第二大的数

这个题是刚刚在微博上看到的,第一想法就想到了leetcode上关于注水的题,Trapping Rain Water,当时的解法是这样的:通过求第二大的数,来解决注水问题

class Solution {
public:
    int trap(int A[], int n) {
        int left = 0;
        int right = n-1;
        int trap = 0;
        int secHigh = 0;
        while (left < right)
        {
            if(A[left] < A[right])
            {
                secHigh = max(A[left], secHigh);
                trap += secHigh;
                left++;
            }
            else
            {
                secHigh = max(A[right], secHigh);
                trap += secHigh;
                right--;
            }
        }

        return trap;
    }
};

看到代码也可以知道,一次判断left与right,一次判断max,这样每个数就有两次比较,而16个数也要30次比较,很明显不能满足要求。
后来看到某牛人的解法,叙述如下:
1、16个数分两组,每组8个,进行两两比较选择较大的,得到8个较大数的数组。这样有8次比较。
2、将8个数同样分两组,得到4个数,这样有4次比较。
3、在继续划分,则有2次比较,最后得到一次比较,这样共8+4+2+1=15次比较得到了最大数M。
4、第二大的数为与最大数进行过比较的数,一共有4个,在这4个数中找到最大的即为整个数组中第二大数S。这样有3此比较,则一共有15+3=18次比较。
关于第4步的解释如下:M最大,M比其他数都大,则M一定会剩下,如果S与M进行比较,则S属于与M比较的数组内,如果S与其他数比较,则S一定会剩下,那么S一定会与M进行比较,所以S一定存在于与M进行过比较的数组内。
举例如下:
数组{5, 3, 12, 14, 1, 8, 9, 13 , 4, 16, 10, 6, 7, 11, 2, 15}
第一次比较: 共8次比较
第一组:5, 3, 12, 14, 1, 8, 9, 13 ,
第二组:4,16, 10, 6, 7, 11, 2, 15
剩下:5,16,12,14, 7,11,9,15 共4次比较
同样比较剩下:7,16, 12,15 共2次比较
继续:12,16 共1次比较
最后得到:16
与16比较过的数为:12,15,11,3 共3次比较
其中最大的为15,所以数组中第二大数为15. 共比较18次。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值