Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/363.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用分治法查找重复次数最多的数字?_Java_Algorithm_Dynamic Programming_Divide And Conquer - Fatal编程技术网

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];

我有一个整数数组列表,它是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];
}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;
    }