To understand that, you must notice the second requirement of the exercise: returning the position where the element should be inserted.
Suppose you want to insert the number 150 in the following table.
╔═════╦═════╦═════╦═════╗
║ 100 ║ 200 ║ 300 ║ 400 ║
╠═════╬═════╬═════╬═════╣
║ 0 ║ 1 ║ 2 ║ 3 ║
╚═════╩═════╩═════╩═════╝
The way this is done is creating a larger array, copying all the elements that come before 150 in the same position that they are, then adding the number 150, then copying all the numbers that come after 150 with one index higher than they were.
╔═════╦═════╦═════╦═════╦═════╗
║ ║ ║ ║ ║ ║
╠═════╬═════╬═════╬═════╬═════╣
║ 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 ║
╚═════╩══════╩═════╩═════╩═════╝
Now that you know how this works, you know that the index you need for insertion is the one of the first number that is greater than your target
. If all numbers are greater than your target
, this means 0 (and all the existing numbers will be shifted to places 1 through N), and if all numbers are less than your target
, this will be the number N - the length of the existing array (it's not a legal index in the existing array, but as I explained, if you really wanted to insert the number, you'd have to create a new array. But that's not part of this exercise).
Now, why is start
the correct index?
When the element you are looking for is not in the array, the middle
element is never matching. So you keep moving the start
and last
closer and closer to each other. In the last iteration, you end up with them pointing to the same element. In this case, start == middle == last
.
Now, the element that they are both pointing to is either greater than target
or less than target
.
Less than target
else if(target>nums[middle]){
start=middle+1;
}
After this statement, we have last
and middle
still pointing to the nums[middle]
number which is less than target
. But start
is going to point one position after it. The number after nums[middle]
is the first number that is greater than target
. If you don't understand why, think how we got to this situation from the previous iteration. The index last
always points to a number that is greater than target
, until it is moved one position "too much", which is what we see here.
Greater than target
else
last=middle-1;
In this case, we have just moved last
to a position that is below start
and middle
- which we know is less than *target. So... the current position is *greater*, the position where
last point is *less
, then the current position (which start
and middle
are still pointing to) is the first number that is greater than target
.
In both cases, start
will be pointing to the correct position - that of the first element that is greater than target
.
Let's see it in our example array. When we try to insert 150, what happens?
start
is 0 (100), last
is 3 (400). middle
, by integer division, is (0+3)/2
which is 1 (200). 200 > 150, so we get to the else
, and set last
to middle - 1
and it's 0 (100).
start is still 0 (100), but
lastis now also 0 (100). They are equal, and
middleis now also 0 (100). 100 < 150, so we get to the
else if, and
start` is now set to 1 (200).
So as soon as start
has moved to a number that is greater than target
, we stopped, and indeed, the point of insertion should be 1!
Let's do the same with 350
start
is 0 (100), last
is 3 (400). middle
, by integer division, is (0+3)/2
which is 1 (200). 200 < 350, so we get to the else if
and start
is now middle +1
, so 2 (300).
start
is 2 (300), last
is 3 (400). middle
is (2+3)/2
which is 2 (300). 300 < 350, so again we get to the else if
and start
is now middle + 1
, so 3 (400).
start
is 3 (400), last
is 3 (400) and middle will be the same. 400 > 350, so we get to the else
, and last
will move to 2 (300).
Now that start
is greater than last
, we see, again, that start
is in fact the first element that is greater than 350. Indeed, the correct insert point for 350 would be 3.