前缀和+差分 | 部分代码整理 | 笔记心得

106 阅读1分钟

前缀和

一维前缀和

package preSum
// 力扣303
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
// 力扣304
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
// 力扣 370
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
// 力扣2536
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
}

参考 | 好文

  1. 面试必会的算法题——前缀和 - 掘金 (juejin.cn)
  2. 啥是前缀和呀?图解前缀和(含模板)| Java 刷题打卡 - 掘金 (juejin.cn)
  3. 二维差分灵佬视频讲解
  4. 二维差分灵佬讲解