Skip to content

Latest commit

 

History

History
49 lines (43 loc) · 2.07 KB

560. 和为K的子数组-Medium.md

File metadata and controls

49 lines (43 loc) · 2.07 KB

给定一个整数数组和一个整数 k,你需要找到该数组中和为 k 的连续的子数组的个数。

示例 1 :

输入:nums = [1,1,1], k = 2
输出: 2 , [1,1]  [1,1] 为两种不同的情况

说明 :

数组的长度为 [1, 20,000]。 数组中元素的范围是 [-1000, 1000] ,且整数 k 的范围是 [-1e7, 1e7]。

Solution

  • 该题主要是使用了前缀和的思想。前缀和,顾名思义即对所有i∈[0, n-1],统计数组中0~i个元素之和。那么,则可通过解num[i:j] = num[0:j] - num[0:i],对num[i:j]=k的求解。即,将问题转化为挑选一对前缀和,比二者之差是否与k相等。
  • 由上可知,可求一个前缀和数组,并通过暴力法穷举得到答案。但时间复杂度为$O(n^2)$
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
      cnt, n =  0, len(nums)
      pre = [0] * (n + 1)
      for i in range(1, n + 1):
          pre[i] = pre[i - 1] + nums[i - 1]
      for i in range(1, n + 1):
          for j in range(i, n + 1):
              if (pre[j] - pre[i - 1] == k): cnt += 1
      return cnt
  • 因此,可使用哈希表来进行优化。使用哈希表存储某数值(前缀和key)与该值对应的组合数量(value)之间的映射。那么,若$current=k$,则结果+1;若当前前缀和$current-k$(将current理解为num[0:j])在该哈希表中,说明可以找到sum2cnt[current-k]num[0:i]符合题目要求。
class Solution:
    def subarraySum(self, nums: List[int], k: int) -> int:
        current, cnt = 0, 0
        sum2cnt = {} # 记录前缀和与对应数量的映射

        for i in nums:
            current += i
            if current == k:
                cnt += 1
            if current - k in sum2cnt:
                cnt += sum2cnt[current-k]
            if current in sum2cnt:
                sum2cnt[current] += 1
            else:
                sum2cnt[current] = 1
        return cnt