#702 Search in a Sorted Array of Unknown Size
题目:
This is an interactive problem.
You have a sorted array of unique elements and an unknown size. You do not have an access to the array but you can use the ArrayReader
interface to access it. You can call ArrayReader.get(i)
that:
- returns the value at the
ith
index (0-indexed) of the secret array (i.e.,secret[i]
), or - returns
231 - 1
if thei
is out of the boundary of the array.
You are also given an integer target
.
Return the index k
of the hidden array where secret[k] == target
or return -1
otherwise.
You must write an algorithm with O(log n)
runtime complexity.
解题思路:
因为不知道array的length,想了很久也不知道怎么求出右边界。没办法只能看一下solution。
solution的思路是,右边界从1开始,左边界从0开始。然后对比右边界的值和目标值的大小,如果前者小,那么要扩界。因为要采用二分法,所以右边界的index开始翻倍。一旦右边界的值大于目标值,则确立range。用回传统老办法找target。
# This is ArrayReader's API interface.
# You should not implement it, or speculate about its implementation
# """
#class ArrayReader:
# def get(self, index: int) -> int:
class Solution:
def search(self, reader: 'ArrayReader', target: int) -> int:
# make sure the secret array has valid index 1
if reader.get(1) is not (2**31 - 1):
left, right = 0, 1
else:
if reader.get(0) == target:
return 0
else:
return -1
# make sure the target is within a certain range
while reader.get(right) < target:
left = right
right <<= 1
# find the index of the target if it exists otherwise return -1
while left<=right:
mid = left+((right-left)>>1)
if reader.get(mid) < target:
left = mid + 1
elif reader.get(mid) > target:
right = mid - 1
else:
return mid
return -1
runtime:
看了其他更快的solution解法思路是一样的,所以就不参考了。
ps有个小小的疑惑,为什么sample solution第一步没有排除length可能为1的情况。
后来想明白了,如果length为1那么值直接是2^31-1。直接以这个值为界。
Apr 1st再做了一次。复习巩固一下skill。(翻了一下记录,第一次做是Mar 20th)
思路有些不同。不再确认idx为1时有无值,发现不重要。
# """
# This is ArrayReader's API interface.
# You should not implement it, or speculate about its implementation
# """
#class ArrayReader:
# def get(self, index: int) -> int:
class Solution:
def search(self, reader: 'ArrayReader', target: int) -> int:
l, r = 0, 1
while True:
if reader.get(r) == target:
return r
if reader.get(r) > target:
while l <= r:
m = (l+r)//2
if reader.get(m) > target:
r = m - 1
elif reader.get(m) < target:
l = m + 1
else:
return m
return -1
else:
l = r + 1
r = 2*l
左右标依然逐轮放大,直到右标值大于target为止。若等,则输出右标。这个因为是看选定范围内有无target,所以用的是 template I 的方法。
runtime:
算是有一点点进步:)