Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/361.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 理解稍微修改过的二进制搜索有困难吗?_Java_Data Structures - Fatal编程技术网

Java 理解稍微修改过的二进制搜索有困难吗?

Java 理解稍微修改过的二进制搜索有困难吗?,java,data-structures,Java,Data Structures,大家好,我正在尝试解决leetcode上一个名为“搜索插入位置”的问题。问题是: 问题陈述: 给定排序数组和目标值,如果找到目标,则返回索引。如果不是,则返回按顺序插入的索引 您可以假定阵列中没有重复项 这是一个简单的二进制搜索,我唯一不明白的是,我必须在最后返回下限才能得到正确的答案。我不明白为什么。如果有人能给我解释,我将不胜感激 class Solution { public int searchInsert(int[] nums, int target) { i

大家好,我正在尝试解决leetcode上一个名为“搜索插入位置”的问题。问题是:

问题陈述: 给定排序数组和目标值,如果找到目标,则返回索引。如果不是,则返回按顺序插入的索引

您可以假定阵列中没有重复项

这是一个简单的二进制搜索,我唯一不明白的是,我必须在最后返回下限才能得到正确的答案。我不明白为什么。如果有人能给我解释,我将不胜感激

class Solution {
    public int searchInsert(int[] nums, int target) {
        int start=0;
        int last= nums.length-1;
        
        while(start<=last){
            int middle=(start+last)/2;
            
            if(target==nums[middle]){
                return middle;
            }
             else if(target>nums[middle]){
            start=middle+1;
             }
            else
                last=middle-1;
            
        }
        return start; // this is the part i don't understand. why do i have to return start? 
    }
}
类解决方案{
公共整数搜索插入(整数[]nums,整数目标){
int start=0;
int last=nums.length-1;
while(startnums[中间]){
开始=中间+1;
}
其他的
last=middle-1;
}
return start;//这是我不理解的部分。为什么我必须返回start?
}
}

取决于数组或其分区的大小(偶数或奇数),或者我们设计二进制搜索算法的方式,有时低和高之间会有一个索引差(基于停止标准,可能是
lo
lo取决于数组或其分区的大小(偶数或奇数),或者我们设计二进制搜索算法的方式,有时低和高之间会有一个索引差异(根据停止标准,在找到中点之前,可能是
lo
lo,我们需要初始化起点。每次它检查是否找到目标元素,如果没有找到目标元素,则更新起点。

在找到中点之前,我们需要初始化起点。)起点。每次检查是否找到目标元素时,如果没有找到目标元素,则更新起点。

要了解这一点,您必须注意练习的第二个要求:返回元素应插入的位置。 假设要在下表中插入数字150

╔═════╦═════╦═════╦═════╗
║ 100 ║ 200 ║ 300 ║ 400 ║
╠═════╬═════╬═════╬═════╣
║ 0   ║ 1   ║ 2   ║ 3   ║
╚═════╩═════╩═════╩═════╝
这样做的方式是创建一个更大的数组,将150之前的所有元素复制到它们所在的相同位置,然后添加数字150,然后复制150之后的所有数字,其中一个索引比原来高

╔═════╦═════╦═════╦═════╦═════╗
║     ║     ║     ║     ║     ║
╠═════╬═════╬═════╬═════╬═════╣
║ 0   ║ 1   ║ 2   ║ 3   ║ 4   ║
╚═════╩═════╩═════╩═════╩═════╝

╔═════╦═════╦═════╦═════╦═════╗
║ 100 ║     ║     ║     ║     ║
╠═════╬═════╬═════╬═════╬═════╣
║ 0   ║ 1   ║ 2   ║ 3   ║ 4   ║
╚═════╩═════╩═════╩═════╩═════╝

╔═════╦═════╦═════╦═════╦═════╗
║ 100 ║ 150 ║     ║     ║     ║
╠═════╬═════╬═════╬═════╬═════╣
║ 0   ║ 1   ║ 2   ║ 3   ║ 4   ║
╚═════╩═════╩═════╩═════╩═════╝

╔═════╦══════╦═════╦═════╦═════╗
║ 100 ║  150 ║ 200 ║ 300 ║ 400 ║
╠═════╬══════╬═════╬═════╬═════╣
║ 0   ║ 1    ║ 2   ║ 3   ║ 4   ║
╚═════╩══════╩═════╩═════╩═════╝
现在您知道了这是如何工作的,您知道插入所需的索引是第一个大于
目标的数字之一。如果所有数字都大于
目标,这意味着0(并且所有现有数字都将移到位置1到N),如果所有数字都小于您的
目标
,则这将是数字N-现有数组的长度(它不是现有数组中的合法索引,但正如我所解释的,如果确实要插入数字,则必须创建一个新数组。但这不是本练习的一部分)

现在,为什么
start
是正确的索引

当您要查找的元素不在数组中时,
middle
元素从不匹配。因此,您不断将
start
last
移动得越来越近。在上一次迭代中,它们最终指向同一个元素。在本例中,
start==middle==last

现在,它们都指向的元素要么大于
target
,要么小于
target

小于
目标

else if(target>nums[middle]){
    start=middle+1;
}
else
    last=middle-1;
在这个语句之后,
last
middle
仍然指向小于
target
nums[middle]
数字。但是
start
将指向它后面的一个位置。
nums[middle]后面的数字
是第一个大于
target
的数字。如果您不明白为什么,请想想我们是如何从上一次迭代中达到这种情况的。索引
last
始终指向大于
target
的数字,直到它移动到一个位置“太多”,这就是我们在这里看到的

大于
目标

else if(target>nums[middle]){
    start=middle+1;
}
else
    last=middle-1;
在本例中,我们刚刚将
last
移动到
start
middle
下方的位置,我们知道该位置小于*target
。因此…当前位置是*大*,
last
点的位置是*小
,然后是当前位置(其中
start
middle
仍然指向)是大于
target
的第一个数字

在这两种情况下,
start
将指向正确的位置,即大于
target
的第一个元素的位置

让我们在示例数组中看到它。当我们尝试插入150时,会发生什么

  • start
    是0(100),
    last
    是3(400)。
    middle
    通过整数除法,是
    (0+3)/2
    ,它是1(200).200>150,因此我们到达
    else
    ,并将
    last
    设置为
    middle-1,它是0(100)
  • start仍然是0(100),但是
    last
    现在也是0(100)。它们相等,
    middle
    现在也是0(100)。100<150,所以如果
    start`现在设置为1(200),我们就进入
    else
  • 因此,只要
    start
    移动到大于
    target
    的数字,我们就停止了,事实上,插入点应该是1

    让我们用350做同样的事情

  • start
    是0(100),
    last
    是3(400)。
    middle
    通过整数除法,是
    (0+3)/2
    ,它是1(200)。200<350,所以我们得到
    ,否则如果
    start
    现在是
    middle+1
    ,那么是2(300)
  • start
    是2(300),
    last
    是3(400)。
    middle
    i