按序輸出整數數組中所有出現頻率最高的數字


蛇年過后第一次開工。這次來討論一個簡單的Amazon筆試題,我先拋出來自己的解法,歡迎大家回復更好的算法,我會更新到帖子里。大家一起學習!

題目來自GeeksForGeeks。那是一位牛牛經過10輪筆試+面試成功應聘Amazon后回饋大眾的回憶錄,還有好幾個題目很有意思呢,大家去看看。也許是很久之前的題了,並不見得是Amazon發明滴。

話說今天這個題目大意如下:
Find maximum frequent numbers in an array. If there are more than one numbers with maximum frequency, they display all numbers in ascending order. Ascending order is important.

看起來確實很簡單,如果數字大小有限,干脆開辟一個新數組a,a的每個元素i代表數字i的出現次數,遍歷整數數組更新a即可。如果數字非常大又怎么辦呢?思索了半天只想出來下面兩種差不多的半吊子算法,既不快也不漂亮:

算法一:
1、對數組快速排序
2、遍歷一遍數組,記錄每個數字出現次數到結構體數組frequency,順便記錄最大次數。frequency每個元素記錄[integer, frequency]。
3、遍歷第2步中frequency,輸出所有次數最大的數字
時間復雜度O(nlgn),空間復雜度O(n)

算法二:
1、開辟一個新的數組frequency記錄數字出現次數
2、對數組進行插入排序,查找步驟中如果需要插入,則記錄該數字出現次數為1;如果遇到相等的情況,就不插入,而是將相等的數字出現次數加1;插入同時更新frequency數組,要保證元素和已排序子數組各個元素一一對應
3、遍歷frequency數組,找到最大次數
4、再次遍歷frequency數組,輸出所有次數最大的數字
時間復雜度O(n^n),空間復雜度O(n)

下面是算法二的實現。

View Code
/*
 * most-frequent-number.c
 *
 * by Wang Guibao
 *
 * Amazon tech interview written test problem.
 * http://www.geeksforgeeks.org/amazon-interview-set-21/
 *
 * Problem:
 * Find maximum frequent numbers in an array. If there are more numbers with
 * maximum frequency, they display all numbers in ascending order. Ascending
 * order is important.
 */
#include <stdio.h>

#define MAX_ELE 32

int elements[MAX_ELE + 1];
int frequency[MAX_ELE + 1];
/*
 * Find most frequently appeared number in an array. If there're more than one
 * such numbers, output them in ascending order
 * @param elements: integer array, integers are elements[1...n]
 * @param n       : number of integers in array
 */
void most_frequent_number(int *elements, int n)
{
    int sorted_begin;
    int sorted_end;
    int begin;
    int end;
    int middle;
    int i;
    int j;
    int max_freq = 0;

    sorted_begin = sorted_end = 1;
    frequency[sorted_begin] = 1;

    /* Insert sort the array */
    for (i = 2; i <= n; i++) {
        begin = sorted_begin;
        end = sorted_end;

        while (begin <= end) {
            middle = (begin + end) / 2;
            if (elements[middle] > elements[i]) {
                end = middle - 1;
            }
            else if (elements[middle] < elements[i]) {
                begin = middle + 1;
            }
            else if (elements[middle] == elements[i]) {
                frequency[middle]++;
                break;
            }
        }

        if (end < begin) {
            for (j = sorted_end; j >= begin; j--) {
                elements[j + 1] = elements[j];
                frequency[j + 1] = frequency[j];
            }
            elements[begin] = elements[i];
            frequency[begin] = 1;

            sorted_end++;
        }
    }

    /* Traverse the sorted subarray */
    for (j = 1; j <= sorted_end; j++) {
        if (max_freq < frequency[j]) {
            max_freq = frequency[j];
        }
    }

    /* Output the integer(s) with maximum frequency */
    for (j = 1; j <= sorted_end; j++) {
        if (frequency[j] == max_freq) {
            printf(" %d", elements[j]);
        }
    }
    printf("\n");

    return;
}

int main()
{
    int i = 1;
    int n;

    printf("Number of integers to process: ");
    scanf("%d", &n);

    printf("Input %d integers: ", n);
    for (i = 1; i <= n; i++) {
        scanf("%d", &elements[i]);
    }

    most_frequent_number(elements, n);

    return 0;
}

不知道這個題目時間、空間復雜度能否進一步降低?歡迎大家一起討論哈。


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM