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

Swift中数组多峰值元素查找方案咨询(已有单峰值代码)

如何在Swift中查找数组的所有峰值元素

好问题!你原来的二分法实现确实能高效定位一个峰值,但要获取所有符合条件的峰值(或者统计峰值数量),我们需要换一种思路——毕竟二分法的核心是快速缩小范围找到单个峰值,而不是枚举所有可能的峰值点。

先明确峰值的定义

结合你给出的预期结果[5,6,4],我们这里的峰值指的是:

  • 对于数组中间的元素(索引i,满足0 < i < 数组长度-1):该元素同时大于左右两个相邻元素
  • 对于数组首尾元素:只有当它大于唯一的相邻元素时才算峰值(不过你的示例数组里没有这种情况)

实现代码

1. 收集所有峰值元素

下面的函数会遍历数组,筛选出所有符合条件的峰值:

func findAllPeakElements(_ readings: [Int]) -> [Int] {
    guard readings.count >= 2 else {
        // 数组长度小于2时,不存在符合定义的峰值(若需调整规则,比如单元素算峰值,可修改这里)
        return []
    }
    
    var peaks: [Int] = []
    
    // 检查第一个元素
    if readings[0] > readings[1] {
        peaks.append(readings[0])
    }
    
    // 遍历检查所有中间元素
    for i in 1..<readings.count - 1 {
        let current = readings[i]
        let leftNeighbor = readings[i-1]
        let rightNeighbor = readings[i+1]
        if current > leftNeighbor && current > rightNeighbor {
            peaks.append(current)
        }
    }
    
    // 检查最后一个元素
    if let last = readings.last, let secondLast = readings.dropLast().last {
        if last > secondLast {
            peaks.append(last)
        }
    }
    
    return peaks
}

2. 仅统计峰值数量

如果只需要获取峰值的个数,可以简化代码,避免存储所有峰值元素:

func countPeakElements(_ readings: [Int]) -> Int {
    guard readings.count >= 2 else {
        return 0
    }
    
    var peakCount = 0
    
    // 检查首元素
    if readings[0] > readings[1] {
        peakCount += 1
    }
    
    // 遍历中间元素
    for i in 1..<readings.count - 1 {
        if readings[i] > readings[i-1] && readings[i] > readings[i+1] {
            peakCount += 1
        }
    }
    
    // 检查尾元素
    if let last = readings.last, let secondLast = readings.dropLast().last {
        if last > secondLast {
            peakCount += 1
        }
    }
    
    return peakCount
}

测试你的示例数组

用你提供的数组测试:

let testArray = [1,2,3,4,5,4,3,2,3,4,5,6,5,4,3,2,4,2]
// 收集所有峰值
print(findAllPeakElements(testArray)) // 输出: [5, 6, 4],完全符合你的预期
// 统计峰值数量
print(countPeakElements(testArray)) // 输出: 3

为什么不用二分法?

你原来的二分法时间复杂度是O(log n),但它的逻辑是每次排除一半的数组,只能定位到一个峰值点——因为数组中可能存在多个峰值,它们分布在不同的区间,二分法无法覆盖所有区间,所以要获取所有峰值,必须采用O(n)的遍历方式,这是无法避免的(毕竟每个元素都需要和邻居对比才能确定是否为峰值)。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.15 08:08:25