微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

【算法】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 - A[left];
                left++;
            }
            else
            {
                secHigh = max(A[right],secHigh);
                trap += secHigh - A[right];
                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,第二组:4,16,15 剩下:5,14, 7,15 共4次比较 同样比较剩下:7,16, 12,15 共2次比较 继续:12,16 共1次比较 最后得到:16 与16比较过的数为:12,15,3 共3次比较 其中最大的为15,所以数组中第二大数为15. 共比较18次。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐