Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When to use low < high or low + 1 < high for loop invariant

I've read multiple articles including Jon Bentleys chapter on binary search. This is what I understand about CORRECT binary search logic and it works in the simple tests I did:

binarysearch (arr, low, high, k)
    1. while (low < high)
        2. mid  = low + (high - low)/2
        3. if (arr[mid] == k)
               return mid
        4. if (arr[mid] < k )
               high = mid -1
        5. else 
               low = mid + 1

Now to find the 1st occurence with sorted duplicates, you'd chance line 3 if condition to continue instead of returning mid as

binarysearch_get_first_occur_with_duplicates (arr, low, high, k)
    1. while (low < high)
        2. mid  = low + (high - low)/2
        3. if (arr[mid] == k)
               high = mid - 1
               low_so_far = arr[mid]
        4. if (arr[mid] < k )
               high = mid -1
        5. else 
               low = mid + 1
        return low_so_far

Similarly to get highest index of repeated element, you'd do low = mid + 1 and continue if arr[mid]==k

This logic seems to be working but in multiple places I see the loop invariant as

while (low + 1 < high)

I am confused and want to understand when you might want to use low + 1 < high instead of low < high.

In the logic I described above low + 1 < high condition leads to errors if you test with simple example.

Can someone clarify why and when we might want to use low + 1 < high in the while loop instead of low < high?

like image 281
user2664398 Avatar asked Oct 21 '22 03:10

user2664398


1 Answers

If your invariant is that the target must lie in low <= i <= high, then you use while (low < high); if your invariant is that the target must lie in low <= i < high then you use while (low + 1 < high). [Thanks to David Eisenstat for confirming this.]

like image 189
Rafe Avatar answered Nov 15 '22 09:11

Rafe