Given an array that’s sorted but rotated at some unknown pivot, in which all elements are distinct, find a “peak” element in O(log N) time.
An element is considered a peak if it is greater than both its left and right neighbors. It is guaranteed that the first and last elements are lower than all others.
In a rotated sorted array, we can use binary search to find a peak efficiently. The key insight is that if we’re at a position where the element is smaller than its right neighbor, there must be a peak to the right. Similarly, if it’s smaller than its left neighbor, there must be a peak to the left.
classSolution {
public:int findPeak(vector<int>& nums) {
int n = nums.size();
if (n ==1) return nums[0];
if (n ==2) return max(nums[0], nums[1]);
int left =1, right = n -2;
while (left <= right) {
int mid = left + (right - left) /2;
if (nums[mid] > nums[mid -1] && nums[mid] > nums[mid +1]) {
return nums[mid];
}
if (nums[mid] < nums[mid +1]) {
left = mid +1;
} else {
right = mid -1;
}
}
return-1; // Should not reach here given problem constraints
}
};
classSolution {
publicintfindPeak(int[] nums) {
int n = nums.length;
if (n == 1) return nums[0];
if (n == 2) return Math.max(nums[0], nums[1]);
int left = 1, right = n - 2;
while (left <= right) {
int mid = left + (right - left) / 2;
if (nums[mid]> nums[mid - 1]&& nums[mid]> nums[mid + 1]) {
return nums[mid];
}
if (nums[mid]< nums[mid + 1]) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return-1; // Should not reach here given problem constraints }
}
classSolution:
deffindPeak(self, nums: List[int]) -> int:
n = len(nums)
if n ==1:
return nums[0]
if n ==2:
return max(nums[0], nums[1])
left, right =1, n -2while left <= right:
mid = left + (right - left) //2if nums[mid] > nums[mid -1] and nums[mid] > nums[mid +1]:
return nums[mid]
if nums[mid] < nums[mid +1]:
left = mid +1else:
right = mid -1return-1# Should not reach here given problem constraints
In a rotated sorted array, the maximum element (which was originally at the end) becomes a natural peak after rotation. We can find this rotation point efficiently using binary search, and it will always be a peak since it’s the largest element.
classSolution {
public:int findPeakUsingRotation(vector<int>& nums) {
int n = nums.size();
if (n ==1) return nums[0];
int left =0, right = n -1;
while (left < right) {
int mid = left + (right - left) /2;
if (nums[mid] > nums[right]) {
left = mid +1;
} else {
right = mid;
}
}
// left points to minimum element, so maximum is at (left - 1 + n) % n
int maxIdx = (left -1+ n) % n;
return nums[maxIdx];
}
};
classSolution {
publicintfindPeakUsingRotation(int[] nums) {
int n = nums.length;
if (n == 1) return nums[0];
int left = 0, right = n - 1;
while (left < right) {
int mid = left + (right - left) / 2;
if (nums[mid]> nums[right]) {
left = mid + 1;
} else {
right = mid;
}
}
// left points to minimum element, so maximum is at (left - 1 + n) % nint maxIdx = (left - 1 + n) % n;
return nums[maxIdx];
}
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
classSolution:
deffindPeakUsingRotation(self, nums: List[int]) -> int:
n = len(nums)
if n ==1:
return nums[0]
left, right =0, n -1while left < right:
mid = left + (right - left) //2if nums[mid] > nums[right]:
left = mid +1else:
right = mid
# left points to minimum element, so maximum is at (left - 1 + n) % n max_idx = (left -1+ n) % n
return nums[max_idx]