寻找峰值

图文题解仓库地址: https://github.com/gofish2020/leetcode_forever

题目:162. 寻找峰值

寻找峰值

思路

题目要求:

  • nums[-1] = nums[n] = -∞
  • 实现时间复杂度为 O(log n) 的算法
  • 峰值含义:左元素 < 峰值元素 > 右元素,即同时大于左右元素的元素

应该要求时间复杂度为O(log n),所以应该能想到二分法求解。二分法求解代码套路如下:

1.定义left / right 两个指针,分别指向数组的两端
2.计算mid = left + (right - left)/2
3.判断mid是否符合题目要求,如果符合返回mid元素
4.如果不符合,左移left++,或者右移right--

伪代码如下:

left ,right := 0,len(nums)-1
for left <= right {
mid := left +( right -left)/2

if mid == target {
return mid
} else if mid < target {
left++
} else mid > target {
right--
}
}

在求峰值的时候存在3种情况:

  • left < mid值  && mid值 > right,例如[1,3,2],如果mid指向3,那么mid就是要找的峰值
  • left < mid值  && mid值 < right,例如[1,2,3],如果mid指向2,左边满足,右边不满足,那就让mid向右移动,指向3的话,2 < 3 && 3 > -∞ 右边界
  • left > mid && mid > right ,例如 [3,2,1],如果mid指向2,右边满足,左边不满足,那就让mid向左移动,指向指向3的话,2 < 3 && 3 > -∞ 左边界

完整代码

func findPeakElement(nums []int) int {
n := len(nums)

get := func ( i int) int {
if i < 0 || i >= n {
return math.MinInt // 题目要求如果越界,都是无穷小-∞
}
return nums[i]
}
left,right := 0,len(nums)-1

for left <= right {
mid := left + (right-left)/2 // 找到中点元素

// mid大于相邻的元素
if get(mid) > get(mid+1) && get(mid) > get(mid-1) {
return mid
} else if get(mid) < get(mid+1) { // mid < right
left = mid+1
} else if get(mid) < get(mid-1) { // mid < left
right = mid-1
}
}
return 0
}


原文始发于微信公众号(nullbody笔记):寻找峰值

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 举报,一经查实,本站将立刻删除。

文章由极客之音整理,本文链接:https://www.bmabk.com/index.php/post/223813.html

(0)
小半的头像小半

相关推荐

发表回复

登录后才能评论
极客之音——专业性很强的中文编程技术网站,欢迎收藏到浏览器,订阅我们!