Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.
Example 1:
Input:nums = [1,1,1], k = 2 Output: 2
Note:
- The length of the array is in range [1, 20,000].
- The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].
這道題給了我們一個數組,讓我們求和為k的連續子數組的個數,博主最開始看到這道題想着肯定要建立累加和數組啊,然后遍歷累加和數組的每個數字,首先看其是否為k,是的話結果 res 自增1,然后再加個往前的循環,這樣可以快速求出所有的子數組之和,看是否為k,參見代碼如下:
解法一:
class Solution { public: int subarraySum(vector<int>& nums, int k) { int res = 0, n = nums.size(); vector<int> sums = nums; for (int i = 1; i < n; ++i) { sums[i] = sums[i - 1] + nums[i]; } for (int i = 0; i < n; ++i) { if (sums[i] == k) ++res; for (int j = i - 1; j >= 0; --j) { if (sums[i] - sums[j] == k) ++res; } } return res; } };
上面的求累加和的方法其實並沒有提高程序的執行效率,跟下面這種暴力搜索的解法並沒有什么不同,博主很驚奇 OJ 居然這么大度,讓這種解法也能通過,參見代碼如下:
解法二:
class Solution { public: int subarraySum(vector<int>& nums, int k) { int res = 0, n = nums.size(); for (int i = 0; i < n; ++i) { int sum = nums[i]; if (sum == k) ++res; for (int j = i + 1; j < n; ++j) { sum += nums[j]; if (sum == k) ++res; } } return res; } };
論壇上大家比較推崇的其實是這種解法,用一個哈希表來建立連續子數組之和跟其出現次數之間的映射,初始化要加入 {0,1} 這對映射,這是為啥呢,因為我們的解題思路是遍歷數組中的數字,用 sum 來記錄到當前位置的累加和,我們建立哈希表的目的是為了讓我們可以快速的查找 sum-k 是否存在,即是否有連續子數組的和為 sum-k,如果存在的話,那么和為k的子數組一定也存在,這樣當 sum 剛好為k的時候,那么數組從起始到當前位置的這段子數組的和就是k,滿足題意,如果哈希表中事先沒有 m[0] 項的話,這個符合題意的結果就無法累加到結果 res 中,這就是初始化的用途。上面講解的內容順帶着也把 for 循環中的內容解釋了,這里就不多闡述了,有疑問的童鞋請在評論區留言哈,參見代碼如下:
解法三:
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; } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/560
類似題目:
參考資料:
https://leetcode.com/problems/subarray-sum-equals-k/
https://leetcode.com/problems/subarray-sum-equals-k/discuss/102153/Basic-Java-solution
https://leetcode.com/problems/subarray-sum-equals-k/discuss/134689/Three-Approaches-With-Explanation
https://leetcode.com/problems/subarray-sum-equals-k/discuss/102106/Java-Solution-PreSum-%2B-HashMap