峰值元素是指其值严格大于左右相邻值的元素。
给你一个整数数组 nums
,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞
。
你必须实现时间复杂度为 O(log n)
的算法来解决此问题。
第一种暴力法:(虽然通过了但是我觉得不对因为题目要求时间复杂度为 O(log n)现在的时间复杂度为O(n)
)
class Solution {
public int findPeakElement(int[] nums) {
int count=0;
if(nums.length==1){
return 0;
}
for(int i=0;i<nums.length;i++){
if(i==0&&nums[1]<nums[0]){
return 0;
}
if(i==nums.length-1&&nums[nums.length-1]>nums[nums.length-2]){
return nums.length-1;
}
if(nums[i]>nums[i+1]&&nums[i]>nums[i-1]){
return i;
}
}
return -1;
}
}
第二种正确的方法(看题解了)
这个没想到因为我觉得一般的logn的是堆树那种
思路 随便选一个位置,然后不断比较,直到走到最大的位置,最大的位置即为答案
在这里需要考虑边界 因此get方法出现
这里用返回的数字与零作比较来证明条件是否成立
测试用例
nums = [1,2,3,1]
假设随机选的数是最后一个1
n=4;
index=3
首先执行compare(2,3)
num1[]={1,3};
num2[]={1,1}
此时num1[1]>num2[1] 返回1
1<0 因此为false
下一个compare不需要开始了 (&&短路)
进入if-else语句
index=3
num1={1,3};
num2={0,0};
num1[0]!=num2[0]->return 1
index--
index=2
此时执行compare(1,2)<0和compare(2,3)>0可以得出两个都为true
退出循环返回index=2
class Solution {
public int findPeakElement(int[] nums) {
int n = nums.length;
int index = (int) (Math.random() * n);
while (!(compare(nums, index - 1,index) < 0 && compare(nums, index,index + 1) > 0)) {
if (compare(nums, index, index + 1) < 0) {
index++;
} else {
index--;
}
}
return index;
}
public int[] get(int[] nums, int index) {
if (index == -1 || index == nums.length) {
return new int[]{0, 0};
}
return new int[]{1, nums[index]};
}
public int compare(int[] nums, int index1, int index2) {
int[] num1 = get(nums, index1);
int[] num2 = get(nums, index2);
if (num1[0] != num2[0]) {
return num1[0] > num2[0] ? 1 : -1;
}
if (num1[1] == num2[1]) {
return 0;
}
return num1[1] > num2[1] ? 1 : -1;
}
}