按序输出整数数组中所有出现频率最高的数字

蛇年过后第一次开工。这次来讨论一个简单的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;
}

不知道这个题目时间、空间复杂度能否进一步降低?欢迎大家一起讨论哈。

转载于:https://www.cnblogs.com/wangguibao/archive/2013/02/22/most_frequent_integers_in_an_array.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值