LeetCode 题解工作台

数组中的峰值

数组 arr 中 大于 前面和后面相邻元素的元素被称为 峰值 元素。 给你一个整数数组 nums 和一个二维整数数组 queries 。 你需要处理以下两种类型的操作: queries[i] = [1, l i , r i ] ,求出子数组 nums[l i ..r i ] 中 峰值 元素的数目。 …

category

3

题型

code_blocks

7

代码语言

hub

3

相关题

当前训练重点

困难 · 数组·结合·二分·indexed·树

bolt

答案摘要

根据题目描述,对于 $0 < i < n - 1$,如果满足 $nums[i - 1] < nums[i]$ 且 $nums[i] > nums[i + 1]$,我们可以将 视为 ,否则视为 。这样,对于操作 ,即查询子数组 中的峰值元素个数,相当于查询区间 $[l + 1, r - 1]$ 中 的个数。我们可以使用树状数组来维护区间 $[1, n - 1]$ 中 的个数。 而对于操作 ,…

Interview AiBox logo

Interview AiBox 实时 AI 助手,陪你讲清 数组·结合·二分·indexed·树 题型思路

试试 AiBox 面试助手arrow_forward
description

题目描述

数组 arr 中 大于 前面和后面相邻元素的元素被称为 峰值 元素。

给你一个整数数组 nums 和一个二维整数数组 queries 。

你需要处理以下两种类型的操作:

  • queries[i] = [1, li, ri] ,求出子数组 nums[li..ri] 中 峰值 元素的数目。
  • queries[i] = [2, indexi, vali] ,将 nums[indexi] 变为 vali 。

请你返回一个数组 answer ,它依次包含每一个第一种操作的答案。

注意:

  • 子数组中 第一个 和 最后一个 元素都 不是 峰值元素。

 

示例 1:

输入:nums = [3,1,4,2,5], queries = [[2,3,4],[1,0,4]]

输出:[0]

解释:

第一个操作:我们将 nums[3] 变为 4 ,nums 变为 [3,1,4,4,5] 。

第二个操作:[3,1,4,4,5] 中峰值元素的数目为 0 。

示例 2:

输入:nums = [4,1,4,2,1,5], queries = [[2,2,4],[1,0,2],[1,0,4]]

输出:[0,1]

解释:

第一个操作:nums[2] 变为 4 ,它已经是 4 了,所以保持不变。

第二个操作:[4,1,4] 中峰值元素的数目为 0 。

第三个操作:第二个 4 是 [4,1,4,2,1] 中的峰值元素。

 

提示:

  • 3 <= nums.length <= 105
  • 1 <= nums[i] <= 105
  • 1 <= queries.length <= 105
  • queries[i][0] == 1 或者 queries[i][0] == 2
  • 对于所有的 i ,都有:
    • queries[i][0] == 1 :0 <= queries[i][1] <= queries[i][2] <= nums.length - 1
    • queries[i][0] == 20 <= queries[i][1] <= nums.length - 1, 1 <= queries[i][2] <= 105
lightbulb

解题思路

方法一:树状数组

根据题目描述,对于 0<i<n10 < i < n - 1,如果满足 nums[i1]<nums[i]nums[i - 1] < nums[i]nums[i]>nums[i+1]nums[i] > nums[i + 1],我们可以将 nums[i]nums[i] 视为 11,否则视为 00。这样,对于操作 11,即查询子数组 nums[l..r]nums[l..r] 中的峰值元素个数,相当于查询区间 [l+1,r1][l + 1, r - 1]11 的个数。我们可以使用树状数组来维护区间 [1,n1][1, n - 1]11 的个数。

而对于操作 11,即把 nums[idx]nums[idx] 更新为 valval,只会影响到 idx1idx - 1, idxidx, idx+1idx + 1 这三个位置的值,因此我们只需要更新这三个位置即可。具体地,我们可以先把这三个位置的峰值元素去掉,然后更新 nums[idx]nums[idx] 的值,最后再把这三个位置的峰值元素加回来。

时间复杂度 O((n+q)×logn)O((n + q) \times \log n),空间复杂度 O(n)O(n)。其中 nnqq 分别是数组 nums 的长度和查询数组 queries 的长度。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
class BinaryIndexedTree:
    __slots__ = "n", "c"

    def __init__(self, n: int):
        self.n = n
        self.c = [0] * (n + 1)

    def update(self, x: int, delta: int) -> None:
        while x <= self.n:
            self.c[x] += delta
            x += x & -x

    def query(self, x: int) -> int:
        s = 0
        while x:
            s += self.c[x]
            x -= x & -x
        return s


class Solution:
    def countOfPeaks(self, nums: List[int], queries: List[List[int]]) -> List[int]:
        def update(i: int, val: int):
            if i <= 0 or i >= n - 1:
                return
            if nums[i - 1] < nums[i] and nums[i] > nums[i + 1]:
                tree.update(i, val)

        n = len(nums)
        tree = BinaryIndexedTree(n - 1)
        for i in range(1, n - 1):
            update(i, 1)
        ans = []
        for q in queries:
            if q[0] == 1:
                l, r = q[1] + 1, q[2] - 1
                ans.append(0 if l > r else tree.query(r) - tree.query(l - 1))
            else:
                idx, val = q[1:]
                for i in range(idx - 1, idx + 2):
                    update(i, -1)
                nums[idx] = val
                for i in range(idx - 1, idx + 2):
                    update(i, 1)
        return ans
speed

复杂度分析

指标
时间complexity is O((n + q) log n) using a BIT, where n is the array size and q is the number of queries. Space complexity is O(n) for storing peaks and BIT structure.
空间Depends on the final approach
psychology

面试官常问的追问

外企场景
  • question_mark

    The problem expects efficient peak counting under frequent updates.

  • question_mark

    Mentioning a BIT or Segment Tree is a strong signal you understand range update patterns.

  • question_mark

    Handling boundary indices correctly is often probed for robustness.

warning

常见陷阱

外企场景
  • error

    Not updating neighboring peak indicators after a value change, leading to incorrect counts.

  • error

    Forgetting to check array bounds when computing peaks, causing runtime errors.

  • error

    Using naive recalculation of all peaks per query results in TLE for large inputs.

swap_horiz

进阶变体

外企场景
  • arrow_right_alt

    Compute valleys instead of peaks using similar BIT or Segment Tree logic.

  • arrow_right_alt

    Allow range increments for type-1 queries, requiring more advanced lazy propagation.

  • arrow_right_alt

    Count peaks modulo a number to combine peak counting with numeric constraints.

help

常见问题

外企场景

数组中的峰值题解:数组·结合·二分·indexed·树 | LeetCode #3187 困难