如何在阵列中找到三个最常见的元素?我正在使用长度为10,000的数组,其中元素= 0-100的随机整数。
我正在考虑使用两个数组,一个长度为100,只是使用if语句递增。但是,我想知道是否有一种方法只能使用一个for / if循环(语句)来查找这些值。
答案 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;
}
抱歉,这是一个糟糕的解决方案,但它的工作方式就像你问的那样,希望有所帮助