###### tags: `Leetcode` `medium` `array` `hash` `prefix sum` `python` `c++` `Top 100 Liked Questions` # 560. Subarray Sum Equals K ## [題目連結:] https://leetcode.com/problems/subarray-sum-equals-k/ ## 題目: Given an array of integers ```nums``` and an integer ```k```, return the total number of subarrays whose sum equals to ```k```. A subarray is a contiguous **non-empty** sequence of elements within an array. **Example 1:** ``` Input: nums = [1,1,1], k = 2 Output: 2 ``` **Example 2:** ``` Input: nums = [1,2,3], k = 3 Output: 2 ``` ## 解題想法: * 此題為求數組中有多少個連續子數組的和等於k * 使用hash table紀錄前綴和 * dic: * key:當前數字+之前的數組的總和 * val:此總和出現次數 * 通過每次用當前位置累計的部分和totalSum * **去找尋字典中key為totalSum-k是否存在** * 若存在: 表示多了dic[totalSum-k]種可以總和為k的情況 * 解釋: 即對於每個位置的值,皆求以該位置為結尾且**和為K的區間**的個數,並更新res * 因為字典紀錄了各位置的連續和 * 所以res紀錄每個連續區間是否可以扣掉前面的其他連續區間得到總和為K * trace: ``` ex: nums=[1, 3, 1, 4, -4], k=4 總共組合數應該要有4個 (1,3)、(3,1)、(4)、(3,1,4,-4) num= 1 3 1 4 -4 部分和: 0 1 4 5 9 5 dic: key紀錄部分和、val紀錄出現數量 初始: dic[0]=1 nums=1: dic[1]=1 nums=3: 因為此時部分和為4,4-k=0,dic[0]存在,所以res+=dic[0],且dic[4]=1 nums=1: 因為此時部分和為5,5-k=1,dic[1]存在,所以res+=dic[1],且dic[5]=1 nums=4: 此時部分和為9, 9-k=5,dic[5]存在,所以res+=dic[5], 且dic[9]=1 nums=-4: 此時部分和為5, 5-k=1, dic[1]存在,所以res+=dic[1], 且更新dic[5]=2 例如 nums[2]=1 ,其部分和為5 所以需要找5-k=1,dic[1]=1: 表示前面區間和為1的區間有1個,即開頭的nums[0]=1 所以區間nums[1]、nums[2]: [3,1]即為一組和為k的解 ``` ## Python: ``` python= from collections import defaultdict class Solution(object): def subarraySum(self, nums, k): """ :type nums: List[int] :type k: int :rtype: int """ #dic的key為該位置+之前的數組的總和 val為出現次數 #sum累加所有數 每到一個新位置 往dic找sum-k是否存在 dic=defaultdict(int) res=0 #出現次數 totalSum=0 dic[0]=1 #初始: 和為0:啥都不加入 出現1次 for val in nums: totalSum+=val if totalSum-k in dic: res+=dic[totalSum-k] dic[totalSum]+=1 print(dic) return res nums=[1,3,1,4,-4,4] k=4 result=Solution() ans=result.subarraySum(nums,k) print(ans) ``` ## C++: ``` cpp= class Solution { public: int subarraySum(vector<int>& nums, int k) { unordered_map<int, int> dic={{0, 1}}; int res=0, curSum=0; for (int val: nums){ curSum+=val; if (dic.count(curSum-k)) //exist in dic res+=dic[curSum-k]; dic[curSum]+=1; } return res; } }; ```