Java 为什么在这个二进制搜索中返回低而不是高?

Java 为什么在这个二进制搜索中返回低而不是高?,java,arrays,duplicates,binary-search,Java,Arrays,Duplicates,Binary Search,给定包含n+1个整数的未排序数组nums,其中 整数介于1和n(含)之间,请证明至少有一个 必须存在重复编号。假设只有一个副本 号码,找到重复的那个 注意: 不能修改数组(假定数组为只读) 只能使用常量O(1)额外空间 数组中只有一个重复的数字,但可以重复多次 对于注释1,我们不能对数组进行排序,对于注释2,我们不能使用哈希。我想我们可以在这里使用二进制搜索 假设我们有一个重复编号为4的数组: [1, 4(was 2), 3, 4, 5, 6, 4(was 7), 8, 9, 4] 我们的想法

给定包含n+1个整数的未排序数组nums,其中 整数介于1和n(含)之间,请证明至少有一个 必须存在重复编号。假设只有一个副本 号码,找到重复的那个

注意:

  • 不能修改数组(假定数组为只读)

  • 只能使用常量O(1)额外空间

  • 数组中只有一个重复的数字,但可以重复多次

  • 对于注释1,我们不能对数组进行排序,对于注释2,我们不能使用哈希。我想我们可以在这里使用二进制搜索

    假设我们有一个重复编号为4的数组:

    [1, 4(was 2), 3, 4, 5, 6, 4(was 7), 8, 9, 4]
    
    我们的想法是通过范围过滤器(如[7,9])观察阵列,可能发生两种情况:

    案例1:范围包含重复的元素,在这种情况下,我们可以在过滤器中找到的元素数量必须大于它应该拥有的元素数量。例如,如果我们看[3,4],我们会发现5个元素。如果没有发生重复,则应该只有两个[3,4]

    这是正确的,因为其他一些元素可以重命名为该组,但不能重命名为其他组。在本例中,元素的预期数量为[3,4],但我们有一个额外的4(作为副本),然后在中重命名了两个4,这就是为什么我们有5个

    案例2:范围不包含重复的元素,在这种情况下,我们可以在筛选器中找到的元素数必须等于或小于元素数

    下面是我的更新的代码。最后一行我不确定该回哪一个。虽然我测试发现low是正确的,但我仍然不知道原因

    public int findDuplicate(int[] nums) {
        int low = 1, high = nums.length - 1;
        while(low <= high){
            int mid = low + (high - low) / 2;
            int count = 0;
           //count the number of elements in the filter [low,mid]
            for(int i = 0; i < nums.length; i++){
                if(nums[i] <= mid && nums[i]>=low){
                    count++;
                }
            }
            if(count > mid-low+1){  //the duplicate would be in the left half
                high = mid;
            } else {          //the duplicate would be in the right half
                low = mid + 1;
            }
        }
        return low; // Why we should return low here, not high?
    }
    
    public int findDuplicate(int[]nums){
    int low=1,high=nums.length-1;
    而(low-mid-low+1){//副本将位于左半部分
    高=中;
    }否则{//副本将位于右半部分
    低=中+1;
    }
    }
    返回低位;//为什么我们应该在这里低回报,而不是高回报?
    }
    
    不清楚为什么您认为必须返回
    而不是
    。我怀疑你没有用很多不同的输入测试这个。对于输入1、1、2,高电平和低电平均为0。无论您返回的是
    high
    还是
    low
    ,答案都将不正确

    换言之:

    • 实现没有正确地解决问题,给出了错误的结果
    • “撒谎还是高”这个问题是个错误的问题

    对你的算法的解释听起来是对的。问题是,您还没有真正实现您在那里解释的内容。你说的是计算一个范围内的元素,在执行时调整范围的上下限,但是在你的实现中,你计算的是
    nums[I]不是应该是
    count>=mid
    ?因为在这个范围内,元素的数量与范围本身的长度相同,这意味着没有重复项。您应该返回重复值,而不是重复项的索引。您不能返回重复的索引,因为注释3指出,唯一的重复值可能出现2次以上。因此,对于您的示例,重复值是
    4
    ,而不是任何索引
    1
    3
    6
    、或
    9
    。您不能使用二进制搜索,因为数组未排序且无法修改。当count==mid时,[0,mid]中没有重复项,因为数组中的大小为n+1,包含1-n的元素,必须至少有一个副本@斯坦福德:这是棘手的部分。我们不能在输入数组上进行二进制搜索,而是在n上@谢谢你指出!我已经更正了代码。它现在计数
    nums[i]=低