0
点赞
收藏
分享

微信扫一扫

【每日一题】LeetCode162. 寻找峰值【一题三解建议收藏(暴力/模拟/二分法)】

LeetCode162. 寻找峰值 【中等Medium】

写在前面:本质上就是找到数组中极大值(比前后卷(大)的值),然后返回,简单难度

题目描述:
A peak element is an element that is strictly greater than its neighbors.Given an integer array ​​​nums​​, find a peak element, and return its index. If the array contains multiple peaks, return the index to any of the peaks.
You may imagine that ​nums[-1] = nums[n] = -∞​. You must write an algorithm that runs in ​​O(log n)​​​ time.
峰值元素是指其值严格大于左右相邻值的元素。给你一个整数数组 ​​​nums​​,找到峰值元素并返回其索引。数组可能包含多个峰值,在这种情况下,返回 任何一个峰值 所在位置即可。
你可以假设 ​​nums[-1] = nums[n] = -∞​​ 。你必须实现时间复杂度为 ​​O(log n)​ 的算法来解决此问题。
提示:
1 <= nums.length <= 1000
-231 <= nums[i] <= 231 - 1
对于所有有效的 i 都有 nums[i] != nums[i + 1]

Example 1:
Input:
nums = [1,2,3,1]
Output: 2
Explanation: 3 is a peak element and your function should return the index number 2.
输入:nums = [1,2,3,1]
输出:2
解释:3 是峰值元素,你的函数应该返回其索引 2。

Example 2:
Input: nums = [1,2,1,3,5,6,4]
Output: 5
Explanation: Your function can return either index number 1 where the peak element is 2, or index number 5 where the peak element is 6.
输入:nums = [1,2,1,3,5,6,4]
输出:5
解释:你的函数可以返回索引 1,其峰值元素为 2;   或者返回索引 5, 其峰值元素为 6。

题目分析【一题三解】:

 一、暴力模拟、直接从头找,比前后大的,就完事了;【时间复杂度:O(n),n是数组nums的长度。空间复杂度:O(1)】

/**
* 1、首先寻找峰值,我们可以从头遍历数组,找到 极大值 即可
* 2、遍历一遍数组 nums,判断 i 位置的前 nums[i - 1]和后 nums[i + 1]是否都小于 nums[i]
*/
public int findPeakElement(int[] nums) {
int n = nums.length;
for (int i = 0; i < n; i++) { // 遍历一遍数组nums,找到比前后卷(大)的值
boolean ok = true;
if (i - 1 >= 0)
if (nums[i - 1] >= nums[i]) ok = false; // 判断i位置的前nums[i - 1]否都小于nums[i]
if (i + 1 < n)
if (nums[i + 1] >= nums[i]) ok = false; // 判断i位置的前nums[i + 1]否都小于nums[i]
if (ok) return i;
}
return -1;
}

二、 暴力找最大值,找到最卷的nums[index],返回index这个值,就完事了;【时间复杂度:O(n),n是数组nums的长度。空间复杂度:O(1)】

/**
* 1、首先寻找峰值,我们可以从头遍历数组,找到 最大值 即可
* 2、遍历一遍数组 nums,保留最大数的位置 i
*/
public int findPeakElement2(int[] nums) {
int idx = 0;
for (int i = 1; i < nums.length; ++i)
if (nums[i] > nums[idx]) // 看看有没有比nums[index]数了,有就卷输了,淘汰掉
idx = i;
return idx;
}

三、二分法;【时间复杂度:O(logN),n是数组nums的长度。空间复杂度:O(1)】

首先要注意题目条件,在题目描述中出现了 nums[-1] = nums[n] = -∞,这就代表着 只要数组中存在一个元素比相邻元素大,那么沿着它一定可以找到一个峰值,返回这个峰值

/**
* 二分法,时间复杂度:O(logN)
*/
public int findPeakElement1(int[] nums) {
int left = 0, right = nums.length - 1;
while (left < right) { // l 和 r重合,输出峰值位置
int mid = (left + right) >> 1; // 左右指针计算中间位置 m
// 因为题目nums[i] != nums[i + 1],所以只要数组中存在一个元素比相邻元素大,那么沿着它一定可以找到一个峰值
if (nums[mid] > nums[mid + 1]) // 比较 m 与 m+1 的值,如果 m 较大,则左侧存在峰值
right = mid; // 令r = m
else // 如果 m + 1 较大
left = mid + 1; // 则右侧存在峰值,l = m + 1
}
return right;
}

题目来源:力扣(LeetCode)


举报

相关推荐

0 条评论