前缀和
一种重要的预处理,大大降低查询的时间复杂度。原理很简单,如同其字面意思,求list前n个数的和就是前缀和哦例题 303. 区域和检索 - 数组不可变
class NumArray:
def __init__(self, nums: List[int]):
self.nums = nums
# 定义了一个首位元素为0
self.pre_num_sum = [0]
for i in self.nums:
self.pre_num_sum.append(self.pre_num_sum[-1] + i)
# 把首位元素删掉,这里的时间复杂度为o(n) 不合适,就不删了,pythonlist删前面时间复杂度为o(n), 删后面时间复杂度为o(1). 请去看C的实现
# self.pre_num_sum = self.pre_num_sum[1:]
def sumRange(self, left: int, right: int) -> int:
return self.pre_num_sum[right + 1] - self.pre_num_sum[left + 1] + self.nums[left]
struct NumArray {
pre_nums:Vec<i32>
}
/**
* `&self` means the method takes an immutable reference.
* If you need a mutable reference, change it to `&mut self` instead.
*/
impl NumArray {
fn new(nums: Vec<i32>) -> Self {
NumArray{pre_nums:{
let mut t = vec![0];
let mut now_loca = 0;
for i in &nums{
t.push(t[now_loca] + i);
now_loca += 1;
}
t
},
}
}
fn sum_range(&self, left: i32, right: i32) -> i32 {
self.pre_nums[(right + 1) as usize] - self.pre_nums[left as usize] + self.nums_[left as usize]
}
}
当然,前缀和方法不仅仅只针对一位矩阵,还针对二维矩阵:304. 二维区域和检索 - 矩阵不可变。像这种二维前缀和我们有几种求法,可以按行求前缀和后按列连起来等等。
区间覆盖
leetcode周赛最后一题:2251. 花期内花的数目
这种题我倒是也有刷打过几次但是梅总结果所以直接凉凉,,今天写一下这种题目如何解:
题目描述类似于给你一个区间,每次给区间中的值加一,然后求对应某个点的值
这个时候我们应该维护什么样的数组就成了关键,虽然我还不知道原理,我们可以维护这样的一个字典: n = defaultdict(int) , for start, end in blocks(区间): n[start] += 1, n[end] -= 1 , 之后对于我们想要查看的天数,我们遍历到这个点就可以了,woc妙啊