前缀和
一维前缀和
package preSum
type NumArray struct {
arr []int
}
func Constructor(nums []int) NumArray {
num := NumArray{arr: []int{0}}
for k, v := range nums {
num.arr = append(num.arr, num.arr[k]+v)
}
return num
}
func (this *NumArray) SumRange(left int, right int) int {
return this.arr[right] - this.arr[left-1]
}
二维前缀和
package preSum
type NumMatrix struct {
preSum [][]int
}
func Constructor(matrix [][]int) NumMatrix {
m,n:=len(matrix),len(matrix[0])
presum:=make([][]int,m+1)
for i:=0;i<=m;i++{
presum[i]=make([]int, n+1)
}
for i:=0;i<=m;i++{
for j:=0;j<=n;j++{
presum[i+1][j+1]=presum[i+1][j]+presum[i][j+1]-presum[i][j]+matrix[i][j]
}
}
return NumMatrix{preSum: presum}
}
func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
cur:=this.preSum
return cur[row2+1][col2+1]-cur[row2+1][col1]-cur[row1][col2+1]+cur[row1][col1]
}
差分
一维差分
package Diff
func getModifiedArray(length int, updates [][]int) []int {
diff:=make([]int,length+1)
for _,v :=range updates{
l,r,d:=v[0],v[1],v[2]
diff[l]+=d
diff[r+1]-=d
}
for i:=1;i<length;i++{
diff[i]+=diff[i-1]
}
return diff[:length]
}
二维查分
package Diff
func rangeAddQueries(n int, queries [][]int) [][]int {
diff:=make([][]int,n+1)
for i:=0;i<=n;i++{
diff[i]=make([]int, n+1)
}
for _,q:=range queries{
r1,c1,r2,c2,x:=q[0],q[1],q[2],q[3],1
r2++
c2++
diff[r1][c1]+=x
diff[r2][c1]-=x
diff[r1][c2]-=x
diff[r2][c2]+=x
}
ans:=make([][]int,n+1)
for i:=0;i<=n;i++{
ans[i]=make([]int, n+1)
}
for i:=0;i<n;i++{
for j:=0;j<n;j++{
ans[i+1][j+1]=ans[i+1][j]+ans[i][j+1]-ans[i][j]+diff[i][j]
}
}
ans=ans[1:]
for k,_ :=range ans{
ans[k]=ans[k][1:]
}
return ans
}
参考 | 好文
- 面试必会的算法题——前缀和 - 掘金 (juejin.cn)
- 啥是前缀和呀?图解前缀和(含模板)| Java 刷题打卡 - 掘金 (juejin.cn)
- 二维差分灵佬视频讲解
- 二维差分灵佬讲解