【问题标题】:Binary search not working for all test cases二进制搜索不适用于所有测试用例
【发布时间】:2018-02-28 07:51:00
【问题描述】:

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

谁能看出我做错了什么?

【问题讨论】:

  • 您尝试过哪些边缘情况?会不会是大样本量的错误?
  • 请不要在每个递归步骤中复制数组。
  • @clinomaniac 我尝试了相对较小的数组大小(2-12),但似乎一切正常。我希望 Hacker rank 能显示它正在测试的测试用例。
  • @Bytes 我似乎有些站点的测试用例具有非常大的样本量,因此可能会在数组复制或其他东西上抛出异常。除了性能之外,我认为算法本身没有任何问题。
  • @clinomaniac 如何更改数组复制部分以提高性能?

标签: java binary-search


【解决方案1】:

您编码过多而思考不足。

首先,基本情况。如果数组长度为零,则返回"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。这保证了您的算法最终将终止,即不会无限重复。如果你在每次递归调用时缩短数组,你最终必须得到基本情况,它总是返回。

您需要制定一些额外的细节,但不是很多。

【讨论】:

    猜你喜欢
    • 2020-06-06
    • 2018-02-27
    • 2013-12-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-08-12
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多