我试图在Java中实现递归二进制搜索,然而,它并不适用于所有测试用例。我正在进行黑客等级挑战,并没有向我展示我错过的测试用例。当我用自己的案例测试它时,它总是成功测试。我不知道自己错过了什么。
import java.util.Arrays;
public class Project {
public static void main(String [] args){
int[] arr = {1,2,4,7,9,10,11};
Arrays.sort(arr);
String x = findNumber(arr, 10);
System.out.println(x);
}
private static String findNumber(int[] arr, int k) {
int arrLength = arr.length - 1;
int mid = Math.round(Math.abs((arrLength) / 2));
if (arrLength >= mid){
if (arr[mid] == k) {
return "YES";
}
else if (arr[mid] > k) {
int[] newArr = Arrays.copyOfRange(arr, 0, mid);
return findNumber(newArr, k);
}
else if (arr[mid] < k) {
int[] newArr = Arrays.copyOfRange(arr, mid + 1, arrLength + 1);
return findNumber(newArr, k);
}
}
return "NO";
}
}
任何人都可以看到我做错了吗?
答案 0 :(得分:0)
你编码太多而且思考不够。
首先,基本情况。如果数组长度为零,则返回"NO"
。您无法在零长度数组中找到k
。
现在是递归案例。该数组至少有1个元素。可以把它分成 3 部分:大致在中间的单个元素加上两个长度为零或更长的子数组。 总是有一个中间元素,因为该数组至少有一个元素。
索引计算int mid = a.length / 2
可以很好地找到中间位置。 (转储舍入和绝对值。)其余子数组的索引范围为0..mid-1
和mid+1..a.length-1
。
使用mid
,您可以立即查看a[mid]
是否匹配。如果是返回"YES"
。
否则你需要弄清楚哪个子阵列k
所在并以递归方式搜索。
不要制作副本来构建子阵列。使用List
方法subList(from, to)
。这只需要恒定的空间。它只是输入数组的视图,而不是新内存的副本。效率更高。
要使用subList
,您的算法需要接受List
而不是本机Java数组。
请注意,subList
的第二个参数是 exclusive ,因此递归调用将位于a.sublist(0, mid)
或a.sublist(mid+1, a.length)
。
请注意,两个子阵列替代方案始终短于a
。这可以保证您的算法最终会终止,即不会无限重复。如果在每次递归调用时缩短数组,则必须最终到达基本情况,该情况总是返回。
您需要制定一些其他细节,但不是很多。