题目链接
题目:峰值元素是指其值大于左右相邻值的元素。
给定一个输入数组 nums,其中 nums[i] ≠ nums[i+1],找到峰值元素并返回其索引。
数组可能包含多个峰值,在这种情况下,返回任何一个峰值所在位置即可。
你可以假设 nums[-1] = nums[n] = -∞。
示例 1:
输入: nums = [1,2,3,1]
输出: 2
解释: 3 是峰值元素,你的函数应该返回其索引 2。
示例 2:
输入: nums = [1,2,1,3,5,6,4]
输出: 1 或 5
解释: 你的函数可以返回索引 1,其峰值元素为 2;
或者返回索引 5, 其峰值元素为 6。
说明:
你的解法应该是 O(logN) 时间复杂度的。
思路:我的解法是
貌似并不符合说明,但是不知道为啥还是过了,就写一下思路吧:由于峰值是先增后减,所以用up来标志是否增加,1代表增;用down来代表是否先增后减,即 如果down之前up为1 down才能赋值为1,否则只能是0,所以直接down=up就好。在提交过程中,发现如果序列单调递增,,,其实也存在峰值,就是序列的最后一个元素,所以用down2来标志该序列是否为单调递增的,如果down2为0 说明单调递增,返回最后一个元素下标即可。
class Solution {
public int findPeakElement(int[] nums) {
int len = nums.length;
int up = 0;
int down = 0;
int down2 = 0;
List<Integer> list = new ArrayList<>();
for(int i = 1; i < len; i++){
if(nums[i] > nums[i-1]){
up = 1;
}else{
down = up;
down2 = 1;
}
if(up * down == 1){
return i-1;
}
}
if(down2 == 0){
return len - 1;
}
return 0;
}
}
看完别人的思路,瞬间凌乱了,原来对题意理解也不够深入,忽略了题目最后一句话“你可以假设 nums[-1] = nums[n] = -∞。”,同样的 解法,代码也是差距如此之大。
public class Solution {
public int findPeakElement(int[] nums) {
for (int i = 0; i < nums.length - 1; i++) {
if (nums[i] > nums[i + 1])
return i;
}
return nums.length - 1;
}
}
接下来整一波
别人思路:已知题目最左端和最右端元素均无限小,中间元素比两侧都要大,那么本题中一定存在一个峰元素。所以不管中间有多少波峰,只要找到峰元素,我们只需找到刚刚开始下降而未下降的位置,二分查找即可。时间复杂度
参考:https://blog.csdn.net/happyaaaaaaaaaaa/article/details/51590056
public class Solution {
public int findPeakElement(int[] nums) {
int left = 0;
int right = nums.length - 1;
int mid;
while(left < right){
mid = (left + right) / 2;
if(nums[mid] < nums[mid+1]){
left = mid + 1;
}else{
right = mid;
}
}
return left;
}
}