1. 程式人生 > >[leetcode] 560. Subarray Sum Equals K

[leetcode] 560. Subarray Sum Equals K

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:

  1. The length of the array is in range [1, 20,000].
  2. The range of numbers in the array is [-1000, 1000] and the range of the integer k
     is [-1e7, 1e7].

這道題是統計相加和為k的連續子陣列個數,題目難度為Medium。

題目和第523題有些類似,感興趣的同學可以順便看下第523題(傳送門)。

最直觀的想法是遍歷陣列並依次加當前位置的數字,同時用陣列sum記錄下當前位置之前所有數字的相加和,這樣下標[i, j)之間的數字之和就可以用sum[j]-sum[i]來計算,然後通過雙層迴圈,遍歷所有情況來統計滿足條件的子陣列個數。具體程式碼:

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int sz = nums.size(), cnt = 0;
        vector<int> sum(sz+1, 0);
        for(int i=0; i<sz; ++i) sum[i+1] = sum[i] + nums[i];
        for(int i=0; i<sz; ++i) {
            for(int j=i+1; j<=sz; ++j) {
                if(sum[j] - sum[i] == k) ++cnt;
            }
        }
        return cnt;
    }
};

用sum表示從陣列開始位置到當前位置的數字相加和,有了第523題的經驗,我們還可以用Hash Table來儲存sum出現的次數,如果當前位置之前有相加和為sum-k的位置,則這兩個位置之間的數字相加和為k,以當前位置結尾的相加和為k的子陣列個數為hash[sum-k],這樣遍歷整個陣列即可得出滿足條件的子陣列個數。具體程式碼:

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        int sum = 0, cnt = 0;
        unordered_map<int, int> hash;
        
        hash[0] = 1;
        for(auto n:nums) {
            sum += n;
            cnt += hash[sum-k];
            ++hash[sum];
        }
        
        return cnt;
    }
};