2021/5/30-31 刷题笔记区域和检索与前缀和方法
Posted 黑黑白白君
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了2021/5/30-31 刷题笔记区域和检索与前缀和方法相关的知识,希望对你有一定的参考价值。
区域和检索 - 数组不可变
【题目】
给定一个整数数组 nums,求出数组从索引 i 到 j(i ≤ j)范围内元素的总和,包含 i、j 两点。
实现 NumArray 类:
- NumArray(int[] nums) 使用数组 nums 初始化对象
- int sumRange(int i, int j) 返回数组nums 从索引 i 到 j(i ≤ j)范围内元素的总和,包含 i、j 两点(也就是 sum(nums[i], nums[i + 1], … , nums[j]))
示例:
- 输入: [“NumArray”, “sumRange”, “sumRange”, “sumRange”] [[[-2, 0, 3, -5, 2, -1]], [0, 2], [2, 5], [0, 5]]
- 输出: [null, 1, -1, -3]
解释:
NumArray numArray = new NumArray([-2, 0, 3, -5, 2, -1]);
numArray.sumRange(0, 2); // return 1 ((-2) + 0 + 3)
numArray.sumRange(2, 5); // return -1 (3 + (-5) + 2 + (-1))
numArray.sumRange(0, 5); // return -3 ((-2) + 0 + 3 + (-5) + 2 + (-1))
提示:
- 0 <= nums.length <= 104
- -105 <= nums[i] <= 105
- 0 <= i <= j < nums.length
- 最多调用 104 次 sumRange 方法
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-sum-query-immutable
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
【我的方法】
在初始化时用一个数组subsum存储前 i 个元素的和(不含i),则sum[i:j]=subsum[j+1]-subsum[i]。
class NumArray:
def __init__(self, nums: List[int]):
self.subsum=[0]
pre=0
for i in nums:
pre+=i
self.subsum.append(pre)
def sumRange(self, left: int, right: int) -> int:
return self.subsum[right+1]-self.subsum[left]
# Your NumArray object will be instantiated and called as such:
# obj = NumArray(nums)
# param_1 = obj.sumRange(left,right)
# 执行用时:72 ms, 在所有 Python3 提交中击败了67.15%的用户
# 内存消耗:18.1 MB, 在所有 Python3 提交中击败了38.73%的用户
前缀和方法整理
1、初始化时进行预处理:
- 由于会进行多次检索,即多次调用 sumRange,因此为了降低检索的总时间,应该降低 sumRange 的时间复杂度,最理想的情况是时间复杂度 O(1)。
- 为了将检索的时间复杂度降到 O(1),需要在初始化的时候进行预处理。
2、预处理:
- 如果可以在初始化的时候计算出数组 nums 在每个下标处的前缀和,即可满足每次调用 sumRange 的时间复杂度都是 O(1)。
- 小技巧:将前缀和数组的长度设为 n+1 的目的是为了方便计算,不需要对 i=0 的情况特殊处理。
二维区域和检索 - 矩阵不可变
这道题是「303. 区域和检索 - 数组不可变」的进阶,第 303 题是在一维数组中做区域和检索,这道题是在二维矩阵中做区域和检索。
【题目】
给定一个二维矩阵,计算其子矩形范围内元素的总和,该子矩阵的左上角为 (row1, col1) ,右下角为 (row2, col2) 。
示例:给定 matrix = [ [3, 0, 1, 4, 2], [5, 6, 3, 2, 1], [1, 2, 0, 1, 5],[4, 1, 0, 1, 7], [1, 0, 3, 0, 5] ]
sumRegion(2, 1, 4, 3) -> 8
sumRegion(1, 1, 2, 2) -> 11
sumRegion(1, 2,2, 4) -> 12
提示:
- 你可以假设矩阵不可变。
- 会多次调用 sumRegion 方法。
- 你可以假设 row1 ≤ row2 且 col1 ≤ col2 。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/range-sum-query-2d-immutable
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
【我的方法】
1、分解为四块,sum[row1,col1,row2,col2]=sum[0,0,row2,col2]-sum[0,0,row2,col1-1]-sum[0,0,row1-1,col2]+sum[0,0,row1-1,col1-1]
2、所以初始化时定义前缀和subsum[0,0,i,j],先通过一维算出第 i 行的前 j 个的和,再算出前 i 行前 j 行的和。
- 注意:为了避免特殊情况的判断,所以subsum在最左边和最上面各多了一行/列。
class NumMatrix:
def __init__(self, matrix: List[List[int]]):
self.n=len(matrix)
self.m=len(matrix[0])
self.subsum=[[0 for i in range(self.m+1)] for j in range(self.n+1)]
for i in range(1,self.n+1):
self.subsum[i][1]=matrix[i-1][0]
for j in range(1,self.m+1):
self.subsum[i][j]=matrix[i-1][j-1]+self.subsum[i][j-1]
if i>1:
for j in range(1,self.m+1):
self.subsum[i][j]+=self.subsum[i-1][j]
# print(self.subsum)
def sumRegion(self, row1: int, col1: int, row2: int, col2: int) -> int:
sum1=self.subsum[row2+1][col2+1]
sum2=self.subsum[row2+1][col1]
sum3=self.subsum[row1][col2+1]
sum4=self.subsum[row1][col1]
# print(sum1,sum2,sum3,sum4)
return sum1+sum4-sum2-sum3
# Your NumMatrix object will be instantiated and called as such:
# obj = NumMatrix(matrix)
# param_1 = obj.sumRegion(row1,col1,row2,col2)
# 执行用时:300 ms, 在所有 Python3 提交中击败了24.62%的用户
# 内存消耗:24.1 MB, 在所有 Python3 提交中击败了5.01%的用户
以上是关于2021/5/30-31 刷题笔记区域和检索与前缀和方法的主要内容,如果未能解决你的问题,请参考以下文章