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 2^31 - 1 if the i 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.
Since the array size is unknown, we first find an upper bound for the index where the target could be by exponentially increasing the index until we go out of bounds or pass the target. Then, we perform binary search in that range.
// The ArrayReader interface is provided by the problem
classSolution {
public:int search(const ArrayReader& reader, int target) {
int left =0, right =1;
while (reader.get(right) < target) right <<=1;
while (left <= right) {
int mid = left + (right - left) /2;
int val = reader.get(mid);
if (val == target) return mid;
elseif (val > target) right = mid -1;
else left = mid +1;
}
return-1;
}
};
1
2
3
4
5
6
7
8
9
10
11
12
// type ArrayReader interface { Get(index int) int }funcsearch(readerArrayReader, targetint) int {
left, right:=0, 1forreader.Get(right) < target { right<<=1 }
forleft<=right {
mid:=left+ (right-left)/2val:=reader.Get(mid)
ifval==target { returnmid }
ifval > target { right = mid-1 } else { left = mid+1 }
}
return-1}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
// interface ArrayReader { int get(int index); }classSolution {
publicintsearch(ArrayReader reader, int target) {
int left = 0, right = 1;
while (reader.get(right) < target) right <<= 1;
while (left <= right) {
int mid = left + (right - left) / 2;
int val = reader.get(mid);
if (val == target) return mid;
elseif (val > target) right = mid - 1;
else left = mid + 1;
}
return-1;
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
// interface ArrayReader { fun get(index: Int): Int }
classSolution {
funsearch(reader: ArrayReader, target: Int): Int {
var left = 0var right = 1while (reader.get(right) < target) right = right shl 1while (left <= right) {
val mid = left + (right - left) / 2val v = reader.get(mid)
when {
v == target ->return mid
v > target -> right = mid - 1else-> left = mid + 1 }
}
return -1 }
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
# class ArrayReader:# def get(self, index: int) -> int:defsearch(reader, target):
left, right =0, 1while reader.get(right) < target:
right <<=1while left <= right:
mid = (left + right) //2 val = reader.get(mid)
if val == target:
return mid
elif val > target:
right = mid -1else:
left = mid +1return-1
1
2
3
4
5
6
7
8
9
10
11
12
// trait ArrayReader { fn get(&self, index: i32) -> i32; }
pubfnsearch(reader: &impl ArrayReader, target: i32) -> i32 {
let (mut left, mut right) = (0, 1);
while reader.get(right) < target { right <<=1; }
while left <= right {
let mid = left + (right - left) /2;
let val = reader.get(mid);
if val == target { return mid; }
if val > target { right = mid -1; } else { left = mid +1; }
}
-1}
1
2
3
4
5
6
7
8
9
10
11
12
13
// interface ArrayReader { get(index: number): number }
functionsearch(reader: ArrayReader, target: number):number {
letleft=0, right=1;
while (reader.get(right) <target) right<<=1;
while (left<=right) {
constmid=left+ ((right-left) >>1);
constval=reader.get(mid);
if (val===target) returnmid;
if (val>target) right=mid-1;
elseleft=mid+1;
}
return-1;
}