数组中最常见的值

时间:2010-10-11 05:12:32

标签: java arrays elements

如何在阵列中找到三个最常见的元素?我正在使用长度为10,000的数组,其中元素= 0-100的随机整数。

我正在考虑使用两个数组,一个长度为100,只是使用if语句递增。但是,我想知道是否有一种方法只能使用一个for / if循环(语句)来查找这些值。

4 个答案:

答案 0 :(得分:4)

你可以在一个循环中完成,但我认为你仍然需要第二个数组。

即。循环输入数组,每次看到一个值时,都会在'counter'数组中增加相应的索引。但是,还要保留3个“顶级”索引(已排序)。每次递增时,请根据前三个索引中的值检查新值,以确定您可能只需重新排序“顶部”值列表。

答案 1 :(得分:4)

如果你打算在列表中经过一定数量的传递,你需要第二个数据结构。

如果你有该组中值的下限和上限,并且值相对密集,那么计数器数组是一个很好的解决方案。

否则,最好使用Map<Integer, Integer>,其中键是集合的元素,值是计数器。

<强>分析

如果在开始之前没有设置上限/上限,那么你不知道要分配的大数量的计数器。所以你必须对数组进行初步传递才能找到边界......现在你有了两个解决方案。

如果你确实有下限和上限但是集合很稀疏,那么初始化计数数组的成本+找到三个最大计数的成本将主导计算集合元素的成本。如果差异足够大(即输入很大且非常稀疏),HashMap将更快并且将占用更少的内存。

<强>替代地

如果允许更改数组,则可以按升序O(NlogN)对其进行排序,然后在排序数组的单次传递中找到三个最常见的元素。

答案 2 :(得分:1)

可能有更好的方法来做到这一点,但这是一种方式。我刚刚打印了模式数组,但您可以对其进行排序以查看实际发生的数字。这很简单,因为我们知道我们正在弄乱的数字的上限和下限,但如果你不知道那些界限,那么你需要接受斯蒂芬C给出的建议。

public class Main {

    public static void main(String[] args) {

        int i;
        int value;
        //one greater than max value because Math.random always returns a value less than 1.0
        //this number also works good for our mode array size
        int maxValue = 101;
        int[] originalArray = new int[10000];
        int[] modeArray = new int[maxValue];

        for(i = 0; i < originalArray.length; i++){
            value = (int) (Math.random() * maxValue);
            originalArray[i] = value;
        }


        for(i = 0; i < originalArray.length; i++){
            modeArray[originalArray[i]] += 1;
        }

        for(i = 0; i < modeArray.length; i++){
            System.out.println("Number " + i + " occurred " + modeArray[i] + " times");
        }

    }

}

答案 3 :(得分:0)

    //find majority of a value in a array — O(n log n) -> wrost case O(n)
void findMajority(){
    //sort
    sort(begin(sarray),end(sarray));
    //sarray[0] is our first number already counted
    int cont=1;
    int leader = sarray[0];
    //temp variables to know when we changed to a different number
    int tempLeader=0;
    int tempCont=0;
    //loop through sarray.size()
    for(unsigned int i=1; i<size; i++){
        if(tempLeader!=sarray[i]) //if we changed number tempCont is 0
            tempCont=0;

        if(sarray[i]==leader){ //if the current number in the array is our leader then keep counting
            cont++;
        }
        else{ //if not, then our new number will be tempLeader and we count that one
            tempLeader=sarray[i];
            tempCont++;
            if(tempCont>cont){ //its not higher occurences than our last number? skip, else we got a new leader
                leader=tempLeader;
                cont=tempCont;
                tempLeader=0;
                tempCont=0;
            }
        }
    }
    cout << "leader is" << leader << endl;
}
抱歉,这是一个糟糕的解决方案,但它的工作方式就像你问的那样,希望有所帮助