https://labuladong.online/algo/problem-set/perfix-sum/#%E8%A7%A3%E6%B3%95%E4%BB%A3%E7%A0%81-3
适用范围:快速、频繁地计算一个索引区间内的元素之和
303 区域和检索:数组不可变
https://leetcode.cn/problems/range-sum-query-immutable/
class NumArray(object):
def __init__(self, nums):
"""
:type nums: List[int]
"""
self.preSum = [0 for _ in range(len(nums)+1)]
for i in range(1, len(nums)+1):
self.preSum[i] = self.preSum[i-1] + nums[i-1]
def sumRange(self, left, right):
"""
:type left: int
:type right: int
:rtype: int
"""
return self.preSum[right+1] - self.preSum[left]
525 连续数组
https://leetcode.cn/problems/contiguous-array/
class Solution(object):
def findMaxLength(self, nums):
"""
:type nums: List[int]
:rtype: int
"""
if not nums:
return 0
n = len(nums)
preSum = [0 for _ in range(n+1)]
for i in range(1, n+1):
preSum[i] = preSum[i-1] + (-1 if nums[i-1] == 0 else 1)
val2idx = {}
res = 0
# print("preSum:", preSum)
for i in range(0, n+1):
# print("val2idx:", val2idx)
if preSum[i] not in val2idx:
val2idx[preSum[i]] = i
else:
res = max(res, i - val2idx[preSum[i]])
return res
523 连续的子数组和
同余性质:preSum[j] - preSum[i] = n*k -> preSum[j]%k == preSum[i]%k
class Solution(object):
def checkSubarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
n = len(nums)
if n < 2:
return False
preSum = [0 for _ in range(n+1)]
for i in range(1, n+1):
preSum[i] = preSum[i-1] + nums[i-1]
hashSet = set()
for i in range(2, n+1):
hashSet.add(preSum[i-2] % k)
if preSum[i]%k in hashSet:
return True
return False
560 和为k的数组
https://leetcode.cn/problems/subarray-sum-equals-k/description/
难点:用val2idx记录preSum[i]出现的次数
class Solution(object):
def subarraySum(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: int
"""
if not nums:
return 0
n = len(nums)
preSum = [0 for _ in range(n+1)]
for i in range(1, n+1):
preSum[i] = preSum[i-1] + nums[i-1]
val2idx = {}
res = 0
for i in range(0, n+1):
if preSum[i]-k in val2idx:
res += val2idx[preSum[i] - k]
val2idx[preSum[i]] = val2idx.get(preSum[i], 0) + 1
return res