[LeetCode] Subarray Sum Equals K 子陣列和為K
阿新 • • 發佈:2018-12-27
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; } };
類似題目:
參考資料: