[LeetCode] 560. Subarray Sum Equals K 子數組和為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的連續子數組的個數,博主最開始看到這道題想着肯定要建立累加和數組啊,然后遍歷累加和數組的每個數字,首先看其是否為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;
    }
};

 

Github 同步地址:

https://github.com/grandyang/leetcode/issues/560

 

類似題目:

Two Sum

Continuous Subarray Sum

Subarray Product Less Than K

Find Pivot Index

 

參考資料:

https://leetcode.com/problems/subarray-sum-equals-k/

https://leetcode.com/problems/subarray-sum-equals-k/discuss/102153/Basic-Java-solution

https://leetcode.com/problems/subarray-sum-equals-k/discuss/134689/Three-Approaches-With-Explanation

https://leetcode.com/problems/subarray-sum-equals-k/discuss/102106/Java-Solution-PreSum-%2B-HashMap

 

LeetCode All in One 題目講解匯總(持續更新中...)


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM