我们把符合下列属性的数组A称作山脉:
- A.length >= 3
- 存在0<i<A.length-1使得A[0]<A[1]<…A[i-1]<A[i]>A[i+1]>…>A[A.length - 1]
给定一个确定为山脉的数组,返回任何满足A[0] < A[1] < … A[i-1] < A[i] > A[i+1] > … > A[A.length - 1] 的 i 的值。
示例 1:输入:[0,1,0] 输出:1
示例 2:输入:[0,2,1,0] 输出:1
提示:
1.3 <= A.length <= 10000
2.0 <= A[i] <= 10^6
3.A 是如上定义的山脉
我的思路:
山脉数组,就是一个先递增后递减排序的数组,若想找到山脉数组的峰顶(即为数组中的最大值),只顺序遍历该数组,需要找到第一个变小的元素即可。
我的解法:
class Solution {
public int peakIndexInMountainArray(int[] A) {
for(int i = 1; i < A.length; i++){
if(A[i - 1] > A[i]){
return --i;
}
}
return -1;
}
}
执行用时 :1 ms, 在所有 Java 提交中击败了78.83%的用户
内存消耗 :43.1 MB, 在所有 Java 提交中击败了38.98%的用户
解法分析:
优点:简单明了
缺点:效率低,时间复杂度O(n),面对大规模数据时,性能瓶颈严重
优化思路:
利用二分查找思路
优化解法:
class Solution {
public int peakIndexInMountainArray(int[] A) {
int left = 0;
int right = A.length - 1;
while(left <= right){
int mid = (left + right) / 2;
if((A[mid] > A[mid + 1]) && (A[mid] > A[mid - 1])){
return mid;
} else if((A[mid] > A[mid + 1]) && (A[mid] < A[mid - 1])){
right = mid - 1;
} else {
left = mid +1;
}
}
return -1;
}
}
执行用时 :0 ms, 在所有 Java 提交中击败了100.00%的用户
内存消耗 :43.4 MB, 在所有 Java 提交中击败了32.33%的用户
解法分析:
优点:时间复杂度O(logn),可以保证大规模数据的可用性。
缺点:代码相对复杂,但不难懂。小规模数据时,不如上面算法性能高。