Check each element of arr one by one until you find the first 1. This is simple but inefficient for large arrays, as you may need to scan many elements before finding the transition point.
Since the array is infinite and sorted, we can’t use its length. Instead, we quickly find a range containing the transition point by jumping in powers of two for the index (right), then use binary search within that range (left to right).
Otherwise, repeatedly check arr[right] for increasing right (i.e., 1, 2, 4, 8, …), until you find arr[right] == 1.
Now, the transition point is between indices left and right (where left is the previous value of right).
Perform binary search in arr[left..right] to find the first 1:
For each mid = left + (right - left) // 2, if arr[mid] == 1, update ans = mid and search left half (right = mid - 1); else search right half (left = mid + 1).
classSolution {
public:int findTransition(const vector<int>& arr) {
if (arr[0] ==1) return0;
int left =0, right =1;
while (arr[right] ==0) {
left = right;
right *=2;
}
// Binary search between left+1 and right
int ans =-1;
while (left <= right) {
int mid = left + (right - left) /2;
if (arr[mid] ==1) {
ans = mid;
right = mid -1;
} else {
left = mid +1;
}
}
return ans;
}
};
classSolution {
publicintfindTransition(int[] arr) {
if (arr[0]== 1) return 0;
int left = 0, right = 1;
while (arr[right]== 0) {
left = right;
right *= 2;
}
int ans =-1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (arr[mid]== 1) {
ans = mid;
right = mid - 1;
} else {
left = mid + 1;
}
}
return ans;
}
}
classSolution {
funfindTransition(arr: IntArray): Int {
if (arr[0] ==1) return0var left = 0var right = 1while (arr[right] ==0) {
left = right
right *=2 }
var ans = -1while (left <= right) {
val mid = left + (right - left) / 2if (arr[mid] ==1) {
ans = mid
right = mid - 1 } else {
left = mid + 1 }
}
return ans
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
classSolution:
deffind_transition(self, arr: list[int]) -> int:
if arr[0] ==1:
return0 left, right =0, 1while arr[right] ==0:
left = right
right *=2 ans =-1while left <= right:
mid = left + (right - left) //2if arr[mid] ==1:
ans = mid
right = mid -1else:
left = mid +1return ans
impl Solution {
pubfnfind_transition(arr: &[i32]) -> i32 {
if arr[0] ==1 {
return0;
}
let (mut left, mut right) = (0, 1);
while arr[right] ==0 {
left = right;
right *=2;
}
letmut ans =-1;
while left <= right {
let mid = left + (right - left) /2;
if arr[mid] ==1 {
ans = mid asi32;
right = mid -1;
} else {
left = mid +1;
}
}
ans
}
}
⏰ Time complexity: O(log n) — Exponential search finds the range in O(log n), then binary search finds the transition in O(log n), where n is the index of the first 1.
🧺 Space complexity: O(1) — Only uses a constant amount of extra space.