《算法设计与分析》第十一周作业
标签(空格分隔): 课堂作业
姓名:李**
学号:16340114
题目:Continuous Subarray Sum(https://leetcode.com/problems/continuous-subarray-sum/)
题目概要
给定一串数字nums和一个指定的数字k,寻找nums中有无子串的和是k的整数倍数,即
思路
mod[i][j]表示nums[i…j]的和对k求余之后的余数。
mod[i][j]的计算公式如下:
特别地,当k为零的时候,去掉取模操作。一段数字求和取模为0,说明这段数能被k整除。而当k为零时,只需找出和为零的一段数即可。
最后判断是否存在
零即可。
具体实现
根据计算公式算即可,每一步都取模是为了防止上溢。交上去发现内存溢出了。。。
一番思考后发觉这个题目只是找存在而已,不用把所有结果都保留,并且计算mod[i][j]的时候只依赖于mod[i]这一行,所以计算的时候不需要申请一个矩阵,只需要一个能存下一行的一维数组即可。算完一行之后这个数组就可以不用保留,留给下一行循环利用了。(具体看代码)
心得
这周习题课上完之后,总算是学会了用二维数组去表示问题里的状态了,但是我现在做的这题只击败了1%的选手,说明这题还是有别的更好的算法,但这个通用算法总算是学到了。感觉动态规划还有很多千奇百怪的变形,学习之路道阻且长呀。
源码:
class Solution
{
public:
bool checkSubarraySum(vector<int>& nums, int k)
{
int length = nums.size();
auto mod = vector<int>(length);
for (int i = 0; i < length; ++i)
{
mod[i] = k==0 ? nums[i] : nums[i] % k;
for (int j = i+1; j < length; ++j)
{
mod[j] = mod[j-1] + nums[j];
mod[j] = k==0 ? mod[j] : mod[j] % k;
if (mod[j] == 0)
return true;
}
}
return false;
}
};