---
# System prepended metadata

title: 560. Subarray Sum Equals K
tags: [prefix sum, Leetcode, medium, python, array, c++, Top 100 Liked Questions, hash]

---

###### 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;
    }
};
```