二进制搜索不适用于所有测试用例

时间:2018-02-27 22:05:43

标签: java binary-search

我试图在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";
     }
}

任何人都可以看到我做错了吗?

1 个答案:

答案 0 :(得分:0)

你编码太多而且思考不够。

首先,基本情况。如果数组长度为零,则返回"NO"。您无法在零长度数组中找到k

现在是递归案例。该数组至少有1个元素。可以把它分成 3 部分:大致在中间的单个元素加上两个长度为零或更长的子数组。 总是有一个中间元素,因为该数组至少有一个元素。

索引计算int mid = a.length / 2可以很好地找到中间位置。 (转储舍入和绝对值。)其余子数组的索引范围为0..mid-1mid+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。这可以保证您的算法最终会终止,即不会无限重复。如果在每次递归调用时缩短数组,则必须最终到达基本情况,该情况总是返回。

您需要制定一些其他细节,但不是很多。