int n = arr.size() - 1;
while(arr[n] < arr[n-1] && n > 0) {
n -= 1;
}
return n;
This test case contains two peaks, 7 at index 4 and 5 at index 6. This isnât a valid test case!
Curtesy of Wizardinho, find me on Leet Code
function peakOfMountainArray(arr) {
// WRITE YOUR BRILLIANT CODE HERE
let left=0;
let right=arr.length-1;
while(left<=right){
const mid = Math.floor((left+right)/2);
let peak = arr[mid];
if(peak>arr[mid-1] && peak>arr[mid+1]) return mid;
else if(peak<arr[mid+1]) left=mid+1;
else right=mid-1;
}
return 0;
}
My solution, thoughts?
def peak_of_mountain_array(arr: List[int]) â int:
# WRITE YOUR BRILLIANT CODE HERE
left, right = 0, len(arr) - 1
while left <= right:
mid = (left + right) //2
if arr[mid] > arr[mid - 1] arr[mid] > arr[mid + 1]:
return mid
elif arr[mid] < arr[mid + 1]:
left = mid + 1
else:
right = mid - 1
small typo,
the if condition is missing âandâ
if arr[mid] > arr[mid - 1] and arr[mid] > arr[mid + 1]:
My thoughts also
My solution, if we use âright = midâ instead then our while loop will be âwhile left < rightâ instead of less than or equal to. This works well for us because it takes care of the edge case when we reach the ends of the list, eliminating the need for the condition âif mid == len(arr)-1â
left, right = 0, len(arr)-1
while left < right:
mid = left + (right-left) // 2
if arr[mid] > arr[mid+1]:
right = mid
else:
left = mid + 1
return left
uhh reformatting solution:
left, right = 0, len(arr)-1
while left < right:
mid = left + (right-left) // 2
if arr[mid] > arr[mid+1]:
right = mid
else:
left = mid + 1
return left
Itâs seems like itâs working. Will it work in every situation.
let min = 0, max = arr.length - 1,index = -1;
while (min <= max){
const mid = min + Math.floor( (max -min)/2 );
if (arr[mid-1] < arr[mid]){
index = mid;
min = mid+1;
}else max = mid -1;
}
return index;
If the elements monotonically increase (Always increasing or REMINAING CONSTANT, and never decreasing) in contrast with STRICTLY increasing, then you CANNOT reliably use binary search to solve this. For example, [2 4 2 2 2 2] is a valid input but given that is monotonically increase [2 4] and monotonically decreases [4 2 2 2 2]. If there is a sequence of repeating numbers, you donât know which way to go with binary search and itâs a 50/50 chance that you go the right direction.
yes, it has to be strictly increasing
yes, peak cannot be the first or last element
âstrictlyâ not âstricklyâ
Why we need condition mid == alen-1
?
It works the same way just with if (arr.get(mid) > arr.get(mid + 1))
Hi,
The description clearly says: âNote that the peak element is neither the first nor the last element of the array.â Given this, below is proposed solution where we first handle edge case where if array length is <=2, we can simply return -1 as neither first or last can be peak according to description. And then, since we know now array length would be at least 3, start our search range from index 1 to 2nd last index. Proposed python solution is as below & it passes all tests. Can you help check if below is good?
On sidenote: I had trouble understanding reference solution condition " mid == alen - 1" & in below proposed solution, I think it will not be needed and hence seems cleaner. Thoughts?
def peak_of_mountain_array(arr: List[int]) â int:
# WRITE YOUR BRILLIANT CODE HERE
N= len(arr)
if N<=2:
return -1 #peak elem is neither the first nor the last elem
#Now,we know array has at least 3 elems
lo=1# because prob says:0th cant be peak
hi=N-2 #because prob says: last cant be peak
cur_boundary=-1
while(lo<=hi):
mid = lo + (hi-lo)//2
if(arr[mid+1] < arr[mid]):
cur_boundary = mid
hi=mid-1
else:
lo=mid+1
return cur_boundary
Do we need the case where mid == alen - 1
? The problem states âthe peak element is [not] ⌠the last element of the arrayâ, and we would look to the left at mid == alen - 2
(i.e. the second to last element). So is there any case where weâd look at the last element of the array?
why are we doing this ```
if mid == alen - 1
I have an alternate Java solution which is the inverse, where I looked at arr[i] > arr[i - 1]
. Instead of the padded element at the end, I had to make up for the 0th element, which we know is never the peak.
public static int peakOfMountainArray(List<Integer> arr) {
int peakIdx = -1;
int left = 0;
int right = arr.size() - 1;
while (left <= right) {
int mid = left + (right - left) / 2;
if (mid == 0 || arr.get(mid) > arr.get(mid - 1)) {
peakIdx = mid;
left = mid + 1;
} else {
right = mid - 1;
}
}
return peakIdx;
}
+1, because the Java solution passes the test cases without this check, i.e. Updating the code to this still works:
int mid = left + (right - left) / 2;
if (/*mid == alen-1 ||*/ arr.get(mid) > arr.get(mid + 1)) { /* etc */
I could be wrong, but it doesnât seem possible to search an array [..., n-2, n-1]
where mid = n-1
?
Simple crisp solution in JAVA.
public static int peakOfMountainArray(List arr) {
int left = 0;
int right = arr.size() - 1;
int n = arr.size();
while (left <= right) {
int mid = left + (right - left) / 2;
// check if mid is greater than its immediate neighbors
if(mid + 1 < n && mid - 1 >= 0 && arr.get(mid) > arr.get(mid + 1) && arr.get(mid) > arr.get(mid - 1)){
return mid;
}
// check if mid is less than or equals to immediate rightmost neighbor
if (mid < n - 1 && arr.get(mid) <= arr.get(mid + 1)) {
left = mid + 1;
} else {
right = mid - 1;
}
}
return -1;
}
Awaiting any sort of criticisms.