【Leetcode】1093. Statistics from a Large Sample

题目地址:

https://leetcode.com/problems/statistics-from-a-large-sample/

给定一个描述某个样本的长 n n n数组 A A A A [ i ] A[i] A[i]代表 i i i出现的次数。问这个样本的最小值、最大值、平均值、中位数和众数。题目保证众数一定存在。返回一个浮点型数组。

最小值、最大值和众数很容易求。要求平均值,要先求总和 ∑ i = 0 n − 1 i A [ i ] \sum_{i=0}^{n-1} iA[i] i=0n1iA[i]和总个数 ∑ i = 0 n − 1 A [ i ] \sum_{i=0}^{n-1} A[i] i=0n1A[i],则平均值就是 ∑ i = 0 n − 1 i A [ i ] ∑ i = 0 n − 1 A [ i ] \frac{\sum_{i=0}^{n-1} iA[i]}{\sum_{i=0}^{n-1} A[i]} i=0n1A[i]i=0n1iA[i]。要求中位数,则需要考虑总个数的奇偶性,如果总个数 k = ∑ i = 0 n − 1 A [ i ] k=\sum_{i=0}^{n-1} A[i] k=i=0n1A[i]是奇数,则 A A A前缀和第一次超过 k / 2 + 1 k/2+1 k/2+1的位置即为所求;如果 k k k是偶数,则 A A A前缀和第一次超过 k / 2 k/2 k/2的位置和第一次超过 k / 2 + 1 k/2+1 k/2+1的位置两者平均值即为所求。代码如下:

class Solution {
 public:
  vector<double> sampleStats(vector<int>& cnt) {
    int m = INT_MAX, M = INT_MIN, mode = 0, amount = 0, max_cnt = 0;
    double sum = 0.0;
    for (int i = 0; i < cnt.size(); i++) {
      if (cnt[i]) {
        m = min(m, i), M = max(M, i);
        sum += (double)i * cnt[i];
        amount += cnt[i];
        if (cnt[i] > max_cnt) {
          max_cnt = cnt[i];
          mode = i;
        }
      }
    }

    double ave = sum / amount;
    // 返回序列里第k个数
    auto f = [&](int k) {
      int amount = 0;
      for (int i = m; i <= M; i++) {
        amount += cnt[i];
        if (amount >= k) return i;
      }

      return -1;
    };

    double mean = 0.0;
    if (amount % 2) mean = f(amount / 2 + 1);
    else mean = (f(amount / 2) + f(amount / 2 + 1)) / 2.0;

    return {(double)m, (double)M, ave, mean, (double)mode};
  }
};

时间复杂度 O ( n ) O(n) O(n),空间 O ( 1 ) O(1) O(1)

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值