要理解这一点,您必须注意练习的第二个要求:返回应该插入元素的位置。
假设您要在下表中插入数字 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 ║
╚═════╩══════╩═════╩═════╩═════╝
现在您知道这是如何工作的,您知道插入所需的索引是第一个大于您的target 的数字之一。如果所有数字都大于您的target,这意味着 0(并且所有现有数字将移动到位置 1 到 N),如果所有数字都小于您的 target,这将是数字 N -现有数组的长度(它不是现有数组中的合法索引,但正如我所解释的,如果你真的想插入数字,你必须创建一个新数组。但这不是本练习的一部分)。
现在,为什么start 是正确的索引?
当您要查找的元素不在数组中时,middle 元素永远不会匹配。因此,您不断将start 和last 彼此靠近。在最后一次迭代中,最终它们指向同一个元素。在这种情况下,start == middle == last。
现在,它们都指向的元素要么大于target,要么小于target。
小于target
else if(target>nums[middle]){
start=middle+1;
}
在此语句之后,last 和 middle 仍然指向nums[middle] 数字,该数字小于 target。但是start 将指向它之后的一个位置。 nums[middle] 后面的数字是第一个大于 target 的数字。如果你不明白为什么,想想我们是如何从上一次迭代中得到这种情况的。索引last 总是指向一个大于target 的数字,直到它移动一个位置“太多”,这就是我们在这里看到的。
大于target
else
last=middle-1;
在这种情况下,我们刚刚将last 移动到低于start 和middle 的位置——我们知道它小于*target. So... the current position is *greater*, the position where last point is *less,然后是当前位置(即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 is still 0 (100), but lastis now also 0 (100). They are equal, andmiddleis now also 0 (100). 100 < 150, so we get to theelse if, and start` 现在设置为 1 (200)。
所以一旦start 移动到一个大于target 的数字,我们就停止了,实际上,插入点应该是1!
让我们对 350 做同样的事情
-
start 是 0 (100),last 是 3 (400)。 middle,通过整数除法,是 (0+3)/2,即 1 (200)。 200 else if 和 start 现在是 middle +1,所以 2 (300)。
-
start 是 2 (300),last 是 3 (400)。 middle 是 (2+3)/2,即 2 (300)。 300 else if 和 start 现在是 middle + 1,所以 3 (400)。
-
start 是 3 (400),last 是 3 (400),中间是一样的。 400 > 350,所以我们到达else,last 将移动到 2 (300)。
现在start 大于last,我们再次看到start 实际上是第一个大于350 的元素。实际上,350 的正确插入点应该是3。