You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

关于峰值查找代码的逻辑解析请求——为何这些条件能找到峰值元素?

Ruby数组峰值查找代码逻辑全解析

问题背景

你需要实现一个Ruby方法,接收数字数组,返回所有峰值元素的数组。峰值定义:

  • 首尾元素:大于唯一相邻元素即为峰值
  • 中间元素:同时大于左右两个相邻元素即为峰值

你给出的代码实现如下:

def peak_finder(arr)
  peaks = []
  arr.each_index do |i|
    left = arr[i - 1] # left most num
    mid = arr[i] # mid num
    right = arr[i + 1]# right most num
    if i == 0 && mid > right
      peaks << mid
    elsif i == arr.length - 1 && mid > left
      peaks << mid
    elsif !left.nil? && !right.nil? && mid > right && mid > left #do not understand this condition
      peaks << mid
    end
  end
  peaks
end
p peak_finder([1, 3, 5, 4]) # => [5]

你的疑问是:这些条件如何实现峰值查找,尤其是中间元素的判断逻辑。


逐行拆解代码逻辑

我们可以把代码的判断逻辑分成三个场景,对应数组的首元素、尾元素、中间元素:

1. 首元素的判断(i == 0 && mid > right)

当遍历到数组第一个元素时(索引i=0),它只有右侧一个相邻元素(right = arr[1])。按照峰值定义,只要当前元素mid大于右侧邻居right,就符合峰值要求,直接加入peaks数组。

2. 尾元素的判断(i == arr.length - 1 && mid > left)

当遍历到数组最后一个元素时(索引i = arr.length - 1),它只有左侧一个相邻元素(left = arr[-2])。只要当前元素mid大于左侧邻居left,就符合峰值要求,加入peaks数组。

3. 中间元素的判断(!left.nil? && !right.nil? && mid > right && mid > left)

这个条件可以拆成两部分理解:

  • !left.nil? && !right.nil?:确保当前元素既不是首元素也不是尾元素。因为首元素的left = arr[-1](Ruby中数组负索引取倒数元素,但这里首元素已经单独处理了),尾元素的right = arr[arr.length]会返回nil,所以这两个判断是为了筛选出真正的中间元素(有左右两个有效邻居)。
  • mid > right && mid > left:严格符合中间元素的峰值定义——当前元素必须同时大于左侧和右侧的相邻元素,两个条件都满足才算是峰值。

结合示例走一遍流程

用你给出的测试用例[1, 3, 5, 4]来模拟遍历过程:

  • 索引0:mid=1,right=3,1>3不成立,不加入peaks
  • 索引1:left=1,mid=3,right=5,3>1但3>5不成立,不加入
  • 索引2:left=3,mid=5,right=4,5>3且5>4,满足条件,加入peaks
  • 索引3:mid=4,left=5,4>5不成立,不加入

最终peaks数组就是[5],和预期结果一致。


内容的提问来源于stack exchange,提问作者Hazel Alvarez

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.04.30 09:38:12