Leetcode 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 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。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值