- [Leetcode 3187. Peaks in Array](#Leetcode 3187. Peaks in Array)
- [1. 解题思路](#1. 解题思路)
- [2. 代码实现](#2. 代码实现)
- 题目链接:3187. Peaks in Array
1. 解题思路
这一题算是一个套路题,基本就是典型的segment tree的题目。
对于任意一个query,segment tree可以直接获得对应范围内的peak的数目(需要去除头尾),而对于任意一个元素的update,其可能影响到的peak的位置为包含其前后元素的至多3个值,我们将这三个值分别重新计算然后update一下即可。
剩下的就是segment tree的实现了,关于这部分内容,网上比比皆是,我自己也写过一个博客(经典算法:Segment Tree)来介绍过这部分的内容,这里就不过多展开了,有兴趣的读者直接去看看这部分的内容即可。
2. 代码实现
给出python代码实现如下:
python
class SegmentTree:
def __init__(self, arr):
self.length = len(arr)
self.tree = self.build(arr)
def feature_func(self, *args):
# get the target feature, such as sum, min or max.
return sum(args)
def build(self, arr):
n = len(arr)
tree = [0 for _ in range(2*n)]
for i in range(n):
tree[i+n] = arr[i]
for i in range(n-1, 0, -1):
tree[i] = self.feature_func(tree[i<<1], tree[(i<<1) | 1])
return tree
def update(self, idx, val):
idx = idx + self.length
self.tree[idx] = val
while idx > 1:
self.tree[idx>>1] = self.feature_func(self.tree[idx], self.tree[idx ^ 1])
idx = idx>>1
return
def query(self, lb, rb):
lb += self.length
rb += self.length
nodes = []
while lb < rb:
if lb & 1 == 1:
nodes.append(self.tree[lb])
lb += 1
if rb & 1 == 0:
nodes.append(self.tree[rb])
rb -= 1
lb = lb >> 1
rb = rb >> 1
if lb == rb:
nodes.append(self.tree[rb])
return self.feature_func(*nodes)
class Solution:
def countOfPeaks(self, nums: List[int], queries: List[List[int]]) -> List[int]:
n = len(nums)
peaks = [0 for _ in nums]
for i in range(1, n-1):
if nums[i-1] < nums[i] and nums[i+1] < nums[i]:
peaks[i] = 1
segment_tree = SegmentTree(peaks)
def query_fn(l, r):
if l >= r-1:
return 0
return segment_tree.query(l+1, r-1)
def update_fn(idx, value):
if idx-1 >= 0 and idx+1 < n:
if nums[idx-1] < value and nums[idx+1] < value:
segment_tree.update(idx, 1)
else:
segment_tree.update(idx, 0)
if idx-2 >= 0:
if nums[idx-2] < nums[idx-1] and value < nums[idx-1]:
segment_tree.update(idx-1, 1)
else:
segment_tree.update(idx-1, 0)
if idx+2 < n:
if nums[idx+2] < nums[idx+1] and value < nums[idx+1]:
segment_tree.update(idx+1, 1)
else:
segment_tree.update(idx+1, 0)
nums[idx] = value
return
ans = []
for query in queries:
if query[0] == 1:
ans.append(query_fn(query[1], query[2]))
else:
update_fn(query[1], query[2])
return ans
提交代码评测得到:耗时4598ms,占用内存77.4MB。