精髓
用数学的方法
题目
1915.最美字符串
560.和为 K 的子数组
930.和相同的二元子数组
974.和可被 K 整除的子数组
1371.每个元音包含偶数次的最长子字符串
1542.找出最长的超赞子字符串
1590.使数组和能被 P 整除
前缀和:只要是连续的数组,都可以使用前缀和的方式,来减少一个维度的便利(使连续)
560
前缀和的根本原因:由于需要求的是任意 sum(i,j)的和,如果便利i, j则复杂度为平方。
因此考虑使用和的方式: s(i,j)= total(j) - total(i), 而正好可以使用一个hash来保存所有的total(i) 的个数,这样就可以使
表达式连续起来了,不用考虑是否相邻。
方法:
需要找到:
s(i,j)= total(j) - total(i)
要求:s(i,j)满足 = k, 已知道total(i)的个数,以及s(i,j) = k, 则只用知道j与i的组合关系即可。,j与i没有关系,只要满足i比j小
// 便利所有的j:
for(int j = 0;j<n;j++){
ans += hash[total(j) - k] // total(i)的个数
hash[total(j)] ++;
}
1 用二维数组记录和:长方形内的个数:
or 可以包括的矩阵的个数
递推公式:s(i,j) num of matrixs from 0,0 to i,j
所以矩阵个数: s(i,j) - s(i-x, j) - s(i,j-y) + s(i-x, j-y)
2 用一个hash记录和:和为K的子数组
递推公式:k = s(i,j) = total(j) - total(i);
i<j
因为i一定< j, i, j不相关,所以只用遍历j, 而i不需要:用hash存储:key:total(i), value: 出现的次数