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