Leetcode 560. Subarray Sum Equals K

Leetcode 560. Subarray Sum Equals K

@(Algo Probs)[LeetCode, Algorithm]

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:
Input: nums = [1,1,1], k = 2
Output: 2

这道题要求出一个数列中有多少个子串的和为k。容易想到一个做法就是将所有可能的子串的和求出来。这个过程 O ( n 2 ) 时间复杂度可以实现,也就是方法一所用到的算法。

其实这道题有 O ( n ) 解法,详见方法二。


Solution #1

Time: O ( n 2 )
Space: O ( 1 )

每次迭代求出start到end之间的和,如果等于k则计数器加1。

Each iteration determines the sum between start and end, and if it is equal to k, increment the counter by 1.

class Solution {
public:
    int subarraySum(vector<int>& nums, int k)
    {
        int ret = 0;
        int size = nums.size();

        for(int start = 0; start < size; start++)
        {
            int sum = 0;
            for(int end = start; end < size; end++)
            {
                sum += nums[end];
                if(sum == k)
                    ret++;
            }
        }

        return ret;
    }
};

Solution #2

Time: O(n)
Space: O(n)

这个方法的时间复杂度为O(n),用到了hashtable。从左到右扫描一遍数组,将开头到当前位置的累积和保存到hashtable中,hashtable记录的是该和的出现次数(即key值为累计和,value值为出现的次数)。每次在扫描的位置处,可以得到当前位置的累计和 ( s u m ) ,接下来根据hashtable判断 ( s u m k ) 是否在之前的序列中出现过,如果出现了可以根据value值得到出现的次数。这个value值所代表的次数,就是以当前位置为结尾,有多少个子序列的和值为k。这很好理解,如果有n个子序列的值为 s u m k ,那么分别以这n个子序列的结尾为开头,以当前位置为结尾的子序列的和均为k。

The time complexity of this method is O(n), by using a hash table. And yes, the space complexity is O(n) as well. In this algorithm, we scan the array from left to right only 1 pass. In each interation, we calculate the cumulative sum from the beginning of the array to the current location, and saved the sum into a hash table (e.g., the key of the hash table is the cumulative sum, and the value of the hash table is a counter which counts how many times the cumulative sum appears before current location). At each location, we can get the cumulative sum (noted s u m ), and find out how many times s u m k has appeared before current location by looking up the hash map. Then, we can find out how many subarrays whose ending is current location, and whose sum equals to k. The value of hashtable[sum - k] tells us the answer. Simply because, if there are n subarrays whose sum equals to s u m k , there must be n subarrays whose sum equals to k , the beginning of those subarrays (whose sum equals to k ) is the ending of the subarrays whose sum equals to s u m k , and the ending of subarrays whose sum equals to k is current location.

class Solution {
public:
    int subarraySum(vector<int>& nums, int k)
    {
        map<int, int> cnt;
        int size = nums.size();
        int sum = 0, ret = 0;

        // Assume the sum before the begining of the array is 0
        cnt[0] = 1;

        for(int i = 0; i < size; i++)
        {
            sum += nums[i];

            if( cnt.find(sum - k) != cnt.end() )
                ret += cnt[sum - k];

            if( cnt.find(sum) != cnt.end() )
                cnt[sum]++;
            else
                cnt[sum] = 1;
        }

        return ret;
    }
};

猜你喜欢

转载自blog.csdn.net/zzy_zhangzeyu_/article/details/71267668
今日推荐