leetcode每日一题之区域和检索-数组可修改

404、区域和检索-数组可修改

给你一个数组 nums ,请你完成两类查询。

  • 其中一类查询要求 更新 数组 nums 下标对应的值
  • 另一类查询要求返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 ,其中 left <= right

实现 NumArray 类:

  • NumArray(int[] nums) 用整数数组 nums 初始化对象
  • void update(int index, int val) 将 nums[index] 的值 更新 为 val
  • int sumRange(int left, int right) 返回数组 nums 中索引 left 和索引 right 之间( 包含 )的nums元素的 和 (即,nums[left] + nums[left + 1], …, nums[right])

示例1:

输入:
["NumArray", "sumRange", "update", "sumRange"]
[[[1, 3, 5]], [0, 2], [1, 2], [0, 2]]
输出:
[null, 9, null, 8]

思路:

看到这道题,一想数组不就可以满足这个条件吗?于是简单的写了一下答案。

class NumArray:

    def __init__(self, nums: List[int]):
    		self.nums = nums

    def update(self, index: int, val: int) -> None:
        self.nums[index] = val

    def sumRange(self, left: int, right: int) -> int:
        return sum(self.nums[left: right+1])

如果这样能够,那不就啪啪啪打力扣的脸吗?于是乎,当我按下提交按钮的那一刻,leetcode着实啪啪啪的打了我的脸,超出时间限制。

这段代码写的没毛病啊,那到底什么地方超时了呢?初始化和update应该不会有问题,那么出问题的地方就是在求和,怎样才能够缩小求和的数据量大小了,这个时候脑袋灵光一闪,分组呀,可以先缓存分组的和,然后根据再求范围内分组的和不就行了吗?

那么怎样分组呢?分组的长度为多少合适呢?数组长度的一半,好像没什么太大作用,那就数组长度的开方吧。

from math import sqrt
class NumArray:

    def __init__(self, nums: List[int]):
        n = len(nums)
        size = int(sqrt(n))
        self.nums = nums
        self.sums = []
        # 根据分组大小求出每个分组的和
        for i in range(0, n, int(size)):
            self.sums.append(sum(self.nums[i: i + size]))
        self.size = size

    def update(self, index: int, val: int) -> None:
      	# 修改数组元素值时,也需要同步修改元素所在分组的和的值 +修改值-原始值
        self.sums[index // self.size] += val - self.nums[index]
        self.nums[index] = val

    def sumRange(self, left: int, right: int) -> int:
        size = self.size
        # 根据left和right所在分组进行求和
        # 如果在同一个分组,那么直接返回分组内求和即可
        # 如果不在同一个分组,需要对left所在分组的右侧求和 + right所在分组的左侧求和 + 左右分组中间的分组求和
        l, r = left // size, right // size
        if l == r:
            return sum(self.nums[left: right + 1])
        return sum(self.nums[left: (l + 1) * size]) + sum(self.nums[r*size: right + 1]) + sum(self.sums[l+1:r])
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

溪语流沙

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值