目录
1. 数组的中心下标
2. 除自身以外数组的乘积
3. 和为k的子数组
4. 和可被K整除的子数组
5. 连续数组
6. 矩阵区域和
1. 数组的中心下标
题目链接:724. 寻找数组的中心下标 - 力扣(LeetCode)
题目展示:
题目分析:
这里的思想类似于动态规划,我们需要定义出两个状态表示。
代码实现:
class Solution {
public:
int pivotIndex(vector<int>& nums)
{
int n=nums.size();
vector<int> f(n);
auto g=f;
f[0]=0;
g[n-1]=0;
for(int i=1;i<n;i++)
{
f[i]=f[i-1]+nums[i-1];
}
for(int i=n-2;i>=0;i--)
{
g[i]=g[i+1]+nums[i+1];
}
for(int i=0;i<n;i++)
{
if(f[i]==g[i]) return i;
}
return -1;
}
};
2. 除自身以外数组的乘积
题目链接:238. 除自身以外数组的乘积 - 力扣(LeetCode)
题目展示:
题目分析:
这里需要强调一点,大家不要去死记硬背前缀和的模板,而是要去理解这种思想;比如本题,其实是前缀积,但是本质上和前缀和的思想是一样的。
代码实现:
class Solution {
public:
vector<int> productExceptSelf(vector<int>& nums)
{
int n=nums.size();
vector<int> ret(n);
vector<int> f(n);
auto g=f;
f[0]=1;
g[n-1]=1;
for(int i=1;i<n;i++)
{
f[i]=f[i-1]*nums[i-1];
}
for(int i=n-2;i>=0;i--)
{
g[i]=g[i+1]*nums[i+1];
}
for(int i=0;i<n;i++)
{
ret[i]=f[i]*g[i];
}
return ret;
}
};
3. 和为k的子数组
题目链接:560. 和为 K 的子数组 - 力扣(LeetCode)
题目展示:
题目分析:
代码实现:
class Solution {
public:
int subarraySum(vector<int>& nums, int k)
{
unordered_map<int,int> hash;
hash[0]=1;
int sum=0,ret=0;
for(auto x:nums)
{
sum+=x;
if(hash.count(sum-k)) ret+=hash[sum-k];
hash[sum]++;
}
return ret;
}
};
4. 和可被K整除的子数组
题目链接:974. 和可被 K 整除的子数组 - 力扣(LeetCode)
题目展示:
题目分析:
与上题很类似,但是需要一些补充知识;
代码实现:
class Solution {
public:
int subarraysDivByK(vector<int>& nums, int k)
{
unordered_map<int,int> hash;
hash[0%k]=1;
int sum=0,ret=0;
for(auto x:nums)
{
sum+=x;
int r=(sum%k+k)%k;
if(hash.count(r)) ret+=hash[r];
hash[r]++;
}
return ret;
}
};
5. 连续数组
题目链接:525. 连续数组 - 力扣(LeetCode)
题目展示:
题目分析:
代码实现:
class Solution {
public:
int findMaxLength(vector<int>& nums)
{
unordered_map<int,int> hash;
hash[0]=-1;
int sum=0,ret=0;
for(int i=0;i<nums.size();i++)
{
sum+=nums[i]==0?-1:1;
if(hash.count(sum)) ret=max(ret,i-hash[sum]);
else hash[sum]=i;
}
return ret;
}
};
6. 矩阵区域和
题目链接:1314. 矩阵区域和 - 力扣(LeetCode)
题目展示:
题目分析:
代码实现:
class Solution {
public:
vector<vector<int>> matrixBlockSum(vector<vector<int>>& mat, int k)
{
int m=mat.size();
int n=mat[0].size();
vector<vector<int>> dp(m+1,vector<int>(n+1));
for(int i=1;i<=m;i++)
{
for(int j=1;j<=n;j++)
{
dp[i][j]=dp[i-1][j]+dp[i][j-1]-dp[i-1][j-1]+mat[i-1][j-1];
}
}
vector<vector<int>> ret(m,vector<int>(n));
for(int i=0;i<m;i++)
{
for(int j=0;j<n;j++)
{
int x1=max(0,i-k)+1;
int y1=max(0,j-k)+1;
int x2=min(m-1,i+k)+1;
int y2=min(n-1,j+k)+1;
ret[i][j]=dp[x2][y2]-dp[x1-1][y2]-dp[x2][y1-1]+dp[x1-1][y1-1];
}
}
return ret;
}
};