最近在努力学习算法阿,学到了前缀和这一知识点,
由于天赋不够,努努力来凑,
决定写下什么来记录一下。
首先,什么是前缀和?
好吧,其实我也不太清楚(#捂脸),我的印象就是相当于一个高中数列。数列求和的亚子,相当于记录前n个的和。当我们需要算某个数组中某个区域的和,那么前缀和就很方便了。 比如说求[n.m] 的数即可。
那么前缀和如何求呢,我们可以构造一个前缀和数组,注意:前缀和下标都是从一开始。s(m,n)表示的就是从(m,n)带(1,1)所围成的矩阵中所有数字的和 比如说s(3,3)就是 就是(3,3)到(1,1)之间围成的所有数字的和
我们如果要算(2,2)到(3,3)之间形成的子矩阵,那么就可以借助前缀和数组来算s(3,3) - s (3,1)-s(1,3) + s(1,1) 注意这个(m,n)代表的是一个正方形,并不是坐标,不要想象成某一个点了,他代表的就是某个矩阵中的数,边界并不是某个点,我当时一直是这么想的,不知道有没有人跟我一样有个错误的想法。
关于那个式子怎么来的,大家可以自己画图看看,利用的就是容斥原理,我表示电脑画图还不太会,就拍照看看了(#捂脸) 反正 某个子区域的所有和公式就是
那么前缀和又是怎么来算的呢?
前缀和就是也可以利用拆分算
比如说我们要算s(3,3) 那么把它分成四部分 ,我们要算的s(3,3) 就可以表示为 s(3,2) + s (2,3) -s(2,2) +a(3,3)
所以 求前缀和的公式就是
至于为什么减,自己可以写写看,反正只要记住 坐标所代表的是那个矩形就行,不是某一个点
这个题目对应有的leetcode题 leetcode
go代码
type NumMatrix struct {
sums [][]int
}
func Constructor(matrix [][]int) NumMatrix {
m:=len(matrix)
if m==0{
return NumMatrix{}
}
n:=len(matrix[0])
sums := make([][]int,m+1)
for i := 0; i <= m; i++ {
sums[i] = make([]int, n+1) //初始化前缀和数组
}
for i:=0;i<m;i++{
for j := 0;j<n;j++{
sums[i+1][j+1] = sums[i][j+1] + sums[i+1][j] - sums[i][j] + matrix[i][j]
} //就是记几个公式
}
return NumMatrix{sums}
}
func (this *NumMatrix) SumRegion(row1 int, col1 int, row2 int, col2 int) int {
return this.sums[row2+1][col2+1] - this.sums[row2+1][col1] -this.sums[row1][col2+1] + this.sums[row1][col1]
}
所需要注意的是,由于题目所给的数组是从0,0开始,我们就需要开大一个开成,m+1 n+1,按照对应填进去.
后记
最后,看了一下,写的很乱,主要也是给自己记录一下学习过程,发现写文章真的要考虑很多东西阿,优美的文案,精美的排版,精确的格式。 所以要成为一名好的写作手不是一件很容易的事,所以要多向大佬学习。