《演算法設計與分析》第十一週作業
阿新 • • 發佈:2018-11-26
《演算法設計與分析》第十一週作業
標籤(空格分隔): 課堂作業
文章目錄
姓名:李**
學號: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;
}
};