I am trying to solve the typical binary search question on LeetCode.com:
Given a sorted (in ascending order) integer array nums of n elements and a target value, write a function to search target in nums. If target exists, then return its index, otherwise return -1. So for [-1,0,3,5,9,12], target = 9; the output is
4
.
As per a solution, the invariant used is:
target is within nums[lo ... hi]
However, given this invariant, I am unsure how to determine the boundary conditions:
class Solution {
public int search(int[] nums, int target) {
// Loop invariant: target is within nums[lo ... hi]
int lo = 0, hi = nums.length - 1;
while (lo <= hi) {
int mi = lo + (hi - lo) / 2;
if (nums[mi] == target) {
return mi;
} else if (nums[mi] > target) {
hi = mi - 1;
} else {
lo = mi + 1;
}
}
return -1;
}
}
How did the invariant help us determine:
a. lo<=hi
instead of just lo<hi
in the while loop condition?
b. hi=mi-1
instead of hi=mi
in the else clause?
c. lo=mi+1
instead of lo=mi
in the else clause?
Personally, when I solved the question myself, I used the invariant as a[lo]<=target<=a[hi]
based on this SO answer, but I still had questions analogous to the three above. Sure, I could take a few examples to understand what to do, but I am specifically focusing on using invariants to determine what to do.
I am new to using invariants in binary search, so would appreciate any kind of help. Thanks!
– Jul 16 '20 at 04:39