# 【LeetCode】 560. Subarray Sum Equals K ## Description > Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k. > 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。 > 注意: > * 陣列的大小範圍為 [1, 20,000]。 > * 陣列中的數字大小範圍為 [-1000, 1000] 且k的大小範圍為 [-1e7, 1e7]。 ## Example: ``` Example 1: Input:nums = [1,1,1], k = 2 Output: 2 ``` ## Solution * 很直覺的先想到使用一個`sum[i ,j]`代表從`i`加到`j`的總和,然後使用兩個迴圈跑`i`和`j`,找到所有等於`k`的子陣列。 ```C++=1 class Solution { public: int subarraySum(vector<int>& nums, int k) { int s = nums.size(); int count = 0; vector<vector<int>> dp(s, vector<int>(s, 0)); for(int i = 0; i < s; i++) { for(int j = i; j < s; j++) { if(i == j) dp[i][j] = nums[j]; else dp[i][j] = dp[i][j - 1] + nums[j]; if(dp[i][j] == k) count++; } } return count; } }; ``` * 觀察一下上面的code,兩層的for都和陣列大小`s`有關,因此時間複雜度為`O(n^2)`;送出之後果然吃TLE。 --- * 那麼,我們思考一下如何加速。 * 我們將上面的`sum[i, j]`改為先得到`sum[0, 0] ~ sum[0, s - 1]`,也就是先只算原本`i = 0`的部分。 * 若輸入為`[1, 2, 3]`,得到`[1, 3, 6]`。 * 可以發現`sum[i, j]`其實就等於`sum[0, j] - sum[0, i]`。 * 又因為這題沒有要求陣列內容,只要求數量,因此我們可以使用hash跑一次迴圈就完成。 * `hash[x]`代表目前所有`k + sum[0, i] = x`的數量。(也就是說`x - sum[0, i]= k`) * 得到`sum[0, i]`後,檢查`hash[sum[0, i]]`是否有值(配對成功)。 * 更新hash,讓hash[k + sum[0, i]]++。 * 只須注意hash一開始需要讓`hash[k] = 1`來初始化即可。 * 時間複雜度降為`O(n)`。 ### Code ```C++=1 class Solution { public: int subarraySum(vector<int>& nums, int k) { int s = nums.size(); int count = 0; vector<int> sum_vector(s + 1, 0); unordered_map<int, int> hash; hash[k] = 1; for(int i = 0; i < s; i++) { sum_vector[i + 1] = sum_vector[i] + nums[i]; count += hash[sum_vector[i + 1]]; hash[k + sum_vector[i + 1]] = hash[k + sum_vector[i + 1]] + 1; } return count; } }; ``` ###### tags: `LeetCode` `C++`