560. 和爲K的子數組
給定一個整數數組和一個整數 k,你需要找到該數組中和爲 k 的連續的子數組的個數。
解題思路: 本題一開始以爲是用滑動窗口解題,但是在寫代碼的時候發現,整數數組的值有正有負,和值也不是單調的,因此窗口的收縮方向不好判斷,於是換了種思路。此題的背景是求和,而且是求序列的連續子集和,那麼爲了降低時間複雜度,往往我們會將0到當前索引位置的和值求出來放在一個和值數組中,然後求某段子數組的和值,比如[i,j],只需計算SUM[i,j]=sum[j]-sum[i]+num[i],但是算法的時間複雜度爲,好像至此,OJ也能通過這個解法。然後看了grandyang的解法,再結合本題給出的標籤,哈希,題目認爲的最優解法是哈希解法。
哈希解題思路:我們可以分析下面這個圖,這段序列取自給定數組nums,左邊界是nums的左邊界,右邊界是nums中間某個點,我們分析這個當前狀態,我們的和值k是有中間某段連續序列組成,因此我們依然在遍歷的過程中將當前位置到0-index點的和值求出來,但是我們不用保存在一個數組,僅僅維護一個到當前位置的和值sum即可,在遍歷的過程中,我們將這個和值與它出現的個數用哈希映射起來,那麼當我們遍歷到圖中這個狀態時,我們要判斷和值k是否存在,只需判斷和值sum-k是否存在,順着這個思路,此題可解。
class Solution {
public:
int subarraySum(vector<int>& nums, int k) {
int res = 0, sum = 0, n = nums.size();
unordered_map<int, int> m{{0,1}};
for (int i = 0; i < n; ++i) {
sum += nums[i];
res += m[sum - k];
++m[sum];
}
return res;
}
};
總結
對連續求和值的題做一個簡單的總結和回顧。連續和值的解法一般用和值數組即可降低一個維度的時間複雜度,這是通常解法,若涉及到判斷和值個數的問題,比如這題,那麼需要想到用哈希來記錄值和個數的映射,這個直接想比較難想到,但是另一個想法我們是很常見的,即,當我們需要判斷或者找尋的和值爲k時,若已知我們當前位置到某個位置(常規是起點0-index)的和值,那我們只需要判斷或者找尋從起點位置到某個位置的和值爲sum-k的序列,就可以解決和值爲k的問題了。
參考資料
https://www.cnblogs.com/grandyang/p/6810361.html