如何在下面的序列中找到相同数字的最多出现次数?
1,5,4,3,2,5,3,1,5,3,7,5,7
本案的答案是5
。
我倾向于将每个数字添加到列表中,如果该数字已经在列表中,则递增一个计数器。在这种方法中,我认为我需要为每个数字设置一个计数器。什么是最容易理解的解决方案?
在这种情况下,我正在使用java
这是一次无效的尝试:
略微修改了Steph的答案,但这有效 -
public class Main {
public static void main(String args[]){
int[] numbers = {1,5,4,3,2,5,3,1,5,3,7,5,7,7,7,7,7};
int[] counterArray = new int[numbers.length];
for (int i = 0; i < numbers.length; ++i){
counterArray[numbers[i]] = counterArray[numbers[i]] + 1;
}
int maxNumber = 0;
for (int i = 0; i < numbers.length; ++i){
if(counterArray[i] > counterArray[maxNumber])
{
maxNumber = i;
}
}
System.out.println(maxNumber);
}
}
答案 0 :(得分:1)
由于您希望算法速度快,因此您提出的解决方案确实是最快的。初始化一个大小为10到0的数组,然后简单地:
for (int i: arrayList) ++counterArray[i]
作为一个轻微的平均时间优化,您可以保持找到最常见的两个数字的运行计数器,并停止搜索最常见的数字是否超过第二个最常见的数字,其中是数字的数量还有待检查。
答案 1 :(得分:1)
这给你O(n)处理时间,当你知道你的值将在0到9之间时,内存占用(不计算你已经拥有的初始数组)是O(1),这样{{ 1}}
counterArray = new int[10];
减少过多内存使用量的另一种方法是找到使用O(n)的最小值和最大值,然后创建数组以包含该数量的值(记住将数组位置偏移最小值)。
答案 2 :(得分:0)
算法一(具有O(n)时间复杂度和O(1)内存复杂度):
正如你所说,为每个数字(10个计数器)设置一个计数器并扫描列表一次。 C代码:
//int the_given_array[n];
int counter[10];
int ix, result;
memset(counter,0,10);
for(ix=0; ix<n; ix++) counter[the_given_array[i]]++;
result = 0;
for(ix=1; ix<10; ix++) if(counter[ix]>counter[result]) result = ix;
算法二(具有O(N ^ 2)时间复杂度和O(1)内存复杂度):
注意:如果您处理base10数字(数量有限),这个没有第一个优势!
设置当前目标号码的计数器,并扫描列表以对其进行计数。然后计算另一个数字,依此类推。保持相同数字最多出现的最大值。你必须最多扫描列表n次。为了提高速度,您可能希望使用GPU编程来并行处理每个数字。