1. 程式人生 > 其它 >【Leetcode】1093. Statistics from a Large Sample

【Leetcode】1093. Statistics from a Large Sample

技術標籤:# 二分、位運算與數學java演算法leetcode

題目地址:

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的位置兩者平均值即為所求。程式碼如下:

public class Solution {
    public double[] sampleStats(int[] count) {
        int min = Integer.MAX_VALUE, max = Integer.MIN_VALUE, mode = 0, amount = 0, maxCount = 0;
		// 防止越界,要將sum定義為double型別
        double sum = 0;
        for (int i = 0; i < count.
length; i++) { if (count[i] > 0) { min = Math.min(min, i); max = Math.max(max, i); sum += i * count[i]; amount += count[i]; if (count[i] > maxCount) { maxCount = count[i]; mode = i; } } } double average = sum / amount; int l = 0, r = 0; if (amount % 2 == 0) { l = amount / 2; r = l + 1; } else { l = r = amount / 2 + 1; } boolean odd = amount % 2 != 0; amount = 0; int posl = 0, posr = 0; boolean foundl = false, foundr = false; for (int i = 0; i < count.length; i++) { amount += count[i]; if (amount >= r && !foundr) { posr = i; foundr = true; } if (amount >= l && !foundl) { posl = i; foundl = true; } if (foundl && foundr) { break; } } return new double[]{min, max, average, odd ? posl : (double) (posl + posr) / 2, mode}; } }

時間複雜度 O ( n ) O(n) O(n),空間 O ( 1 ) O(1) O(1)