image.png

解法1:暴力求解

从前往后求和sum[i]为到第i项时候的和

那么sum[i:j] = sum[j]-sum[i]

遍历所有区间,用上面的公式快速求出各个区间的值,符合条件则结果+1

class Solution(object):
    def subarraySum(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: int
        """
        n = len(nums)
        sums = [x for x in nums]

        for index in range(1,n):
            sums[index] = sums[index-1]+nums[index]

        ans = 0
        for start in range(n):
            for end in range(start,n):
                if sums[end]-sums[start]+nums[start]==k:
                    ans+=1

        return ans

时间复杂度:n^2

解法2:哈希表

假如到第i个元素的时候,总和为sum[i] 那么 怎么样得到连续的子数组使得子数组的值为k呢? 很显然,我们可以将sum[i]分为两部分:sum[i] = (sum[i]-k)+k,我们在前边已经得到的sum[x],(0<=x<i)中找到能值等于sum[i]-k的那一个,显然x+1到i部分的值就是k!,这样的x有几个,那么到当前索引i的时候,就会有几个子数组和为k。

所以做法如下:
遍历nums,并且依次记录累加和sum
使用哈希表d 记录累加和出现的次数 (如果出现过+1,没出现过=1)
查询以当前元素结尾的和为k的子数组有多少个,用sum[i]-k则得到与目标k的差距,找到等于差距的累计和的个数,加到结果上

代码

`

class Solution(object):
    def subarraySum(self, nums, k):
        d = {0:1}
        sums = 0

        ans = 0
        for i in range(len(nums)):
            sums+=nums[i]
            find = sums-k

            #
            if find in d:
                ans+=d[find]

            if sums in d:
                d[sums]+=1
            else:
                d[sums] = 1

        return ans

`

时间复杂度n


北语张益达
6 声望4 粉丝