702. Search in a Sorted Array of Unknown Size
Description
Given a big sorted array with non-negative integers sorted by non-decreasing order. The array is so big so that you can not get the length of the whole array directly, and you can only access the kth number by ArrayReader.get(k) (or ArrayReader->get(k) for C++).
Find the first index of a target number. Your algorithm should be in O(log k), where k is the first index of the target number.
Return -1, if the number doesn’t exist in the array.
Thoughts
Think of exponential backoff when seeing the dyanmic array/list.
We can try to search array in the following order:
the first elements
the first 2 elements
the first 4 elements
…
the first 2^i elements
In this way, we extend the search range by one time everytime until we see a number(index i) who is larger than target. The target should be in the range between i and i // 2.
The array is sorted and we know the range. Now we can use binary search to find target.
Code
Time complexity: O(logK)
def searchBigSortedArray(self, reader, target):
'''
Define the search range. Start from length 1
'''
range_total = 1
'''
If the last number is smaller than target, extend the range to 2 * range,
until we see the last number is greater or equal to target.
'''
while reader.get(range_total - 1) < target:
range_total *= 2
'''
Then the target should be in the range [range_total // 2, range_total - 1]
Remember to check the corner case: target <= arr[0].
In this problem, the cases are covered.
'''
start = range_total // 2
end = range_total - 1
while start < end - 1:
mid = (start + end) // 2
if reader.get(mid) >= target:
end = mid
else:
start = mid
'''
We need to find the first target, so need to check the start first.
'''
if reader.get(start) == target:
return start
if reader.get(end) == target:
return end
return -1
Summary
If you can easily find the O(n) solution, try use binary search to improve it to O(logn).
Think of exponential backoff when seeing the dyanmic array/list.