Java 使用分治法查找重复次数最多的数字?
我有一个整数数组列表,它是5,12,5,17,5,5,5,39,我试图找到重复次数最多的数字,它可以打印5 然而,我想用分而治之的方法来写它 任何提示都会有帮助(伪代码、Java代码或任何帮助…)Java 使用分治法查找重复次数最多的数字?,java,algorithm,dynamic-programming,divide-and-conquer,Java,Algorithm,Dynamic Programming,Divide And Conquer,我有一个整数数组列表,它是5,12,5,17,5,5,5,39,我试图找到重复次数最多的数字,它可以打印5 然而,我想用分而治之的方法来写它 任何提示都会有帮助(伪代码、Java代码或任何帮助…) publicstaticvoidmain(字符串[]args){ int[]重复={5,12,5,17,5,5,5,39}; int计数器=1; 内部温度=0; int-checker=1; 数组。排序(重复); int cont=重复[0]; 对于(int i=1;i计数器){ 温度=重复[i];
publicstaticvoidmain(字符串[]args){
int[]重复={5,12,5,17,5,5,5,39};
int计数器=1;
内部温度=0;
int-checker=1;
数组。排序(重复);
int cont=重复[0];
对于(int i=1;i计数器){
温度=重复[i];
}else if(重复[i]!=重复[i-1]){
检查器=1;
}
}
}
系统输出打印项次(温度);
}
为什么要在示例代码中对其进行排序?在这一点上,你可以从一开始就遍历它,找到重复次数最多的
假设您不打算在分而治之之前对其进行排序,您应该计算列表的大小,找到中间点。一般来说,分治是一种类似于合并排序的方法,您可以使用递归。在本例中,您试图使用它来计算每个值-它似乎不是最合适的,因为在执行递归时,您需要以某种方式保持最高计数的状态(这意味着传入一些内容)
与只是在阵列中穿行并在地图或其他东西中计数相比,这里的动机到底是什么。这将是O(n)时间和O(n)空间。分而治之不是一种适用于这里的技术,因为不能保证从整个列表的任何2个子部分得到相同的结果。即使您对列表进行排序,也不会这样做,因为您可能会在子列表之间拆分最大的组,此时您会在每个子列表中找到不同的最大组,并完全忽略正确的结果
正如javagirl所建议的,枚举列表和计数事件绝对是最简单和最好的方法 此代码统计数组中给定数字的出现次数(这不是很有效,但应该可以让您开始)
publicstaticvoidmain(字符串[]args){
int[]重复={5,12,5,17,12,12,5,39};
系统输出打印项次(计数发生次数(重复));
}
公共静态映射计数发生率(int[]arr){
如果(arr.length==1){
映射结果=新的HashMap();
结果.put(arr[0],1);
返回结果;
}否则{
int to=阵列长度/2;
copyOfRange(arr,0,to);
Map left=countoccurrences(Arrays.copyOfRange(arr,0,to));
Map right=countoccurrences(Arrays.copyOfRange(arr,to,arr.length));
返回合并(左、右);
}
}
静态贴图合并(贴图左、贴图右){
对。forEach((数字,计数)->{
compute(number,(num,c)->c==null?count:c+count);
});
左转;
}
你想做什么毫无意义
我认为“分而治之”是“二进制搜索”的一个隐喻,它被用来(顾名思义)搜索——用它来计算是没有意义的
如果你想拥有更好的性能,你有几个不需要排序的选项
与首先对数组排序然后查找最长的序列相比,您可以调整快速排序以更有效地执行此操作(*)。其思路如下:
在快速排序中,您通常选择一个元素x,然后放置元素
您的意思是要查找模式吗?在您的示例中,5和12都出现三次。为清楚起见,您可能应该确保您的示例中只有一个“最重复”的数字。感谢您的警告@JimMischel我已修复它。@johntame您描述的是模式,即“最常出现的值”。对于所有建议使用地图的人来说,这不是OP所要求的。他在问如何使用分而治之的方法。大家都缺少的一点是,如果Arrays.sort()
使用快速排序(一种分而治之的算法),那么他已经解决了他的问题。OP可以说他想在不使用任何显式额外内存的情况下解决问题,例如映射所需的O(n)内存。“这会让事情变得更清楚一些。”JimMischel(高效)的回答修正了这个答案是错误的。首先,分治不仅仅是二进制搜索。你的第一个建议提出了一个不切实际的假设,即内存不是问题,而你的第二个“节省内存”建议忽略了地图可能太大而无法存储的可能性。@JimMischel,请算法与疯狂结构博士回答最初的问题。。。我会很高兴给它加价。。。如果你能做到这一点,并且使用的内存比映射少,那么OP已经展示了如何使用比映射少的内存:排序和计数。我的方法是O(n)his is O(nlogn)。。。另外,这不是“分而治之”,最终你证明了自己,你无法提供满足自己要求的答案。。。干得好胖子我不是OP。OP的问题不可回答,因为没有分而治之的解决方案。那个
public static void main(String[] args) {
int[] repetitive = { 5, 12, 5, 17, 5, 5, 5, 39 };
int counter = 1;
int temp = 0;
int checker = 1;
Arrays.sort(repetitive);
int cont = repetitive[0];
for (int i = 1; i < repetitive.length; i++) {
if (repetative[i] == repetitive[i - 1] && cont == repetitive[i]) {
counter++;
temp = repetitive[i];
} else if (repetitive[i] == repetitive[i - 1]) {
checker++;
if (checker > counter) {
temp = repetitive[i];
} else if (repetitive[i] != repetitive[i - 1]) {
checker = 1;
}
}
}
System.out.println(temp);
}
public static void main(String[] args) {
int[] repetitive = { 5, 12, 5, 17, 12, 12, 5, 39 };
System.out.println(countOccurences(repetitive));
}
public static Map<Integer, Integer> countOccurences(int[] arr) {
if (arr.length == 1) {
Map<Integer, Integer> result = new HashMap<>();
result.put(arr[0], 1);
return result;
} else {
int to = arr.length / 2;
Arrays.copyOfRange(arr, 0, to);
Map<Integer, Integer> left = countOccurences(Arrays.copyOfRange(arr, 0, to));
Map<Integer, Integer> right = countOccurences(Arrays.copyOfRange(arr, to, arr.length));
return merge(left, right);
}
}
static Map<Integer, Integer> merge(Map<Integer, Integer> left, Map<Integer, Integer> right) {
right.forEach((number, count) -> {
left.compute(number, (num, c) -> c == null ? count : c + count);
});
return left;
}