LeetCode 大样本统计

大样本统计

我们对 0 到 255 之间的整数进行采样,并将结果存储在数组 count 中:count[k] 就是整数 k 的采样个数。

我们以 浮点数 数组的形式,分别返回样本的最小值、最大值、平均值、中位数和众数。其中,众数是保证唯一的。

我们先来回顾一下中位数的知识:

如果样本中的元素有序,并且元素数量为奇数时,中位数为最中间的那个元素;
如果样本中的元素有序,并且元素数量为偶数时,中位数为中间的两个元素的平均值。

示例 1:

输入:count = [0,1,3,4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
输出:[1.00000,3.00000,2.37500,2.50000,3.00000]

示例 2:

输入:count = [0,4,3,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0]
输出:[1.00000,4.00000,2.18182,2.00000,1.00000]

提示:

count.length == 256
1 <= sum(count) <= 10^9
计数表示的众数是唯一的
答案与真实值误差在 10^-5 以内就会被视为正确答案

题目分析

第一次做这道题,倒不是因为它很难,而是因为太难通过测试了。首先,这是一道中等题目,首先我就想到了将这个数组还原。例如[0,1,3,4]还原成[1,2,2,2,3,3,3,3]但是,这显然不行,空间复杂度和时间复杂度太高。刚开始我想到了找链表中间结点的快慢指针法,但是我发现,这并不可行。其实求最大最小值,总数,平均数很简单。这道题难就难在怎么求中位数,我想了很久,最后用双指针法将这题解决了。

首先,我们分别在开头与末尾设置一个左指针和右指针(注意,指向的是非0的count),然后如果左指针即count[left]<count[right],左指针右移,并且将右指针的值更新为count[right]-count[left]。对于右指针大于左指针的情况操作类似。

关键来了:我们究竟要如何区分偶数和奇数的情况呢。得分两种情况去考虑

  1. 退出循环时,左指针等于右指针,意味着为奇数,直接取该数作为中位数即可
  2. 退出循环时,左指针大于右指针(刚开始左指针是小于右指针的),中位数取(left+right)/2

注意:除此之外,我们需要考虑的还有整数溢出问题(我被这个卡了很久,由于部分的测试样例太大)。因此,我们在这句中sum = sum + long(i)*(long)count[i];必须这么写,相乘才不会整数溢出。

class Solution {
public:
    vector<double> sampleStats(vector<int>& count) {
        vector<double> ans(5);
        int max = 0;
        int count2 = 0;//统计数量
        long sum = 0;
        bool flag = true;
        for(int i =0;i<=255;i++){
            if(count[i]!=0 && flag){
                ans[0] = i;
                sum = sum + long(i)*(long)count[i];
                count2 += count[i];
                ans[1] = i;
                flag = false;
                if (count[i]>max){
                    max = count[i];
                    ans[4] = i;
                }
                continue;
            }
            else if(count[i]!=0){
                sum = sum + long(i)*(long)count[i];
                count2 += count[i];
                ans[1] = i;
                if (count[i]>max){
                    max = count[i];
                    ans[4] = i;
                }
            }
            //平均值
            ans[2]=double(sum)/double(count2);
        }
        //计算中位数
        double mid;
        int left = 0;
        int right = 255;
        while(left<right){
            while(count[left]==0){
                left++;
            }
            while(count[right]==0){
                right--;
            }
            if (count[left]>count[right]){
                count[left] -= count[right];
                do{
                    right--;
                }while(count[right]==0);
            }
            else if (count[left]<count[right]){
                count[right] -= count[left];
                do{
                    left++;
                }while(count[left]==0);
            }
            else{
                do{
                    right--;
                }while(count[right]==0);
                do{
                    left++;
                }while(count[left]==0);
            }
        }
        if(left==right){
            mid = left;
        }
        else{
            mid = (double(left)+double(right))/2;
        }
        ans[3]=mid;
        return ans;
    }
};
posted @ 2021-10-14 00:08  ChrisNg  阅读(64)  评论(0)    收藏  举报