- Leetcode 3187. Peaks in Array
- 1. 解题思路
- 2. 代码实现
- 题目链接:3187. Peaks in Array
1. 解题思路
这一题算是一个套路题,基本就是典型的segment tree的题目。
对于任意一个query,segment tree可以直接获得对应范围内的peak的数目(需要去除头尾),而对于任意一个元素的update,其可能影响到的peak的位置为包含其前后元素的至多3个值,我们将这三个值分别重新计算然后update一下即可。
剩下的就是segment tree的实现了,关于这部分内容,网上比比皆是,我自己也写过一个博客(经典算法:Segment Tree)来介绍过这部分的内容,这里就不过多展开了,有兴趣的读者直接去看看这部分的内容即可。
2. 代码实现
给出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 treedef update(self, idx, val):idx = idx + self.lengthself.tree[idx] = valwhile idx > 1:self.tree[idx>>1] = self.feature_func(self.tree[idx], self.tree[idx ^ 1])idx = idx>>1returndef query(self, lb, rb):lb += self.length rb += self.lengthnodes = []while lb < rb:if lb & 1 == 1:nodes.append(self.tree[lb])lb += 1if rb & 1 == 0:nodes.append(self.tree[rb])rb -= 1lb = lb >> 1rb = rb >> 1if 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] = 1segment_tree = SegmentTree(peaks)def query_fn(l, r):if l >= r-1:return 0return 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] = valuereturnans = []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。