import java.util.Scanner;
public class Test {
public static void display(int[] arr) {
for (int i = 0; i < arr.length; i++) {
System.out.printf("%d\n", arr[i]);
}
System.out.printf("\n");
}
// this one is the problematic one.
public static int min(int[] arr, int start, int end) {
int middle = start + (end - start)/2;
if (start >= middle) {
return arr[start];
}
int min_1 = min(arr, start, middle);
int min_3 = (min_1 <= arr[middle])? min_1 : arr[middle];
int min_2 = min(arr, middle+1, end);
return (min_3 <= min_2)? min_3 : min_2;
}
public static void main(String[] args) {
int len;
Scanner in = new Scanner(System.in);
System.out.printf("Enter the length of array: ");
len = in.nextInt();
int[] arr = new int[len];
for (int i = 0; i < len; i++) {
arr[i] = (int)(10*Math.random()+1);
}
arr[len-1] = 0;
display(arr);
System.out.printf("%d is the min", min(arr, 0, arr.length-1));
}
}
问题是:方法min()适用于最小数量的其他位置(在本例中为“0”),例如,如果我将“0”放在第3位(通过更改arr [len-1] = 0部分),方法返回0.如果我将输入长度“len”更改为3,7,13或14,则返回0,这对于其他长度(例如4,5,8,9)是正确的返回第二个最小数字。而更有趣的是,如果我将结束点设为“arr.length”而不是“arr.length-1”,它将不会给出一些长度的错误(例如对于len = 6,它会给出ArrayIndexOutOfBoundsException) ),而且它正常工作,并在没有出错的情况下返回0。我真的不明白究竟是什么问题(注意:我必须递归地找到最小数字并找到上半部分和后半部分的min并进行比较,所以其他解决方案对我没有帮助:/)。
答案 0 :(得分:0)
让我们考虑一个执行过程4,让我们说它生成arr = [6,10,2,0]
min()的第一次调用将作为start,end传递0,3。中间将为0 +(3 - 0)/ 2 = 1
所以,你打电话
min_1 = min(arr, 0, 1)
在此执行中min将有中间= 0 +(1 - 0)/ 2 = 0,因此它将返回arr [0],即6。
我们回到外部min(),其中min_3计算为(6到10之间的最小值,即6.然后我们计算min_2 = min(arr,2,3)
我们现在处于min的内部执行中。这里中间= 2 +(3 - 2)/ 2 = 2.当中间==开始时,我们返回arr [2],即2.
我们回到外部min,我们最终计算min_3和min_1之间的min,即2,并返回它。请注意,我们从未处理过arr [3]
这里的问题是你停止递归的条件。这里的想法是,当你已经退化到你正在查看大小为1的interva的情况下,你想要停止递归。这个条件不应该是开始&gt; =中间,而是开始&gt; =结束。