2016年8月30日 星期二

HackerRank Day 0: Mean, Median, and Mode (Tutorials>10 Days of Statistics)

題目:
輸入n個正整數的陣列X,
輸出其平均值,中位數及眾數。
(如有多個眾數則取最小者)

輸入:
第一行為數字n,代表陣列的個數。
第二行為以空格隔開的n個正整數。
輸入限制10 <= N <= 2500,且每個正整數<=10的5次方。

輸出:
分三行輸出平均值(mean),中位數(median),眾數(mode),
如解為小數,則輸出到第1位。

解題:
首先讀入後,先經過排序由小至大。
(這邊還是使用之前用過的qsort)

平均值->加起來除以n即可。

中位數->取n/2,整除的話,
答案是為x[n/2-1]+x[n/2+1-1]的一半,
否則解為x[(n+1)/2-1]。
(-1的原因是因為陣列由0開始,全部平移1單位)
留意%0.1lf可以保證輸出的小數點後面顯示1位。

眾數->在輸入值有限的狀況,使用類似bucket sort的方法。
直接開一個every_cnt[100000]並初始化,
接著依次讀出x[i]的值,並以every_cnt[x[i]]++達到記數的效果。
最後,遍歷各項有值的every_cnt,
經比較即可得出眾數為何。

這個方法較為占用記憶體,但除去前面sorting的部分,
後面進行記數以及查找均為線性的複雜度。
(記數為O(n),查找為遍歷x[0]~10^5)


Code:
#include <stdio.h>
#include <string.h>
#include <math.h>
#include <stdlib.h>

int compare(const void *arg1, const void *arg2){
     return  (*(int *)arg1 - *(int *)arg2);
}

int main() {
    int n;
    scanf("%d\n", &n);
    int x[n];
    double mean = 0.0;
    for(int i = 0; i < n; i++)
    {    
        scanf("%d\n", &x[i]);
        mean += (double) x[i];
    }
    mean /= (double) n;
    printf("%0.1lf\n", mean);
    qsort((void *)x, n, sizeof(int), compare);    
    
    if(n % 2 == 1)
        printf("%d\n", x[(n+1)/2 - 1]);
    else
        printf("%0.1lf\n", (double)(x[n/2 - 1] + x[n/2+1-1])/2.0);
    
    int every_cnt[100000] = {0};
    int max_n = x[0];
    for(int i = 0; i < n; i++){
        every_cnt[x[i]]++;
    }
    
    for(int j = x[0]; j < 100000; j++)
    {
        if(every_cnt[j] == 0) 
            continue;
        if(every_cnt[j] > every_cnt[max_n])
            max_n = j;
    }    
        
    printf("%d\n", max_n);
    
    return 0;
}

沒有留言:

張貼留言