【问题标题】:Find number of subarrays with length <= k and with sum == s查找长度 <= k 且总和 == s 的子数组的数量
【发布时间】:2022-01-05 22:48:20
【问题描述】:

我遇到了以下问题:

给定一个整数数组arr、一个正整数k和一个整数s,你的任务是找到长度不大于k的非空连续子数组的数量,并且总和等于s

对于arr = [1, 2, 4, -1, 6, 1]k = 3s = 6,输出应为solution(arr, k, s) = 3

  • 长度为1的连续子数组中有1子数组 总和等于s = 6,它是[6]
  • 长度为2的连续子数组中有1子数组 总和等于s = 6,它是[2, 4]
  • 长度为3 的连续子数组中有1 子数组 总和等于s = 6,它是[-1, 6, 1]

请注意,子数组[1, 2, 4, -1] 的总和也会等于s,但它的长度大于k,因此不适用。

所以答案是3


以下是我在 Python 中的尝试。我的想法是将每个前缀总和出现的索引存储在字典中。例如,如果前缀和 6 出现在索引 13 处,则字典中的条目将是 6:[1, 3]。然后在每一步我们都可以检查目标和s是否遇到(if curr - s in d:)以及子数组的范围。

这通过了 10/15 的测试用例,但超过了剩余隐藏用例的时间限制。如果有人有优化算法,我将不胜感激。

import collections
def solution(arr, k, s):
    res = 0
    curr = 0
    d = collections.defaultdict(list)
    d[0].append(-1)
    for i, num in enumerate(arr):
        curr += num
        if curr - s in d:
            for idx in d[curr-s]:
                if i - idx <= k:
                    res += 1
        d[curr].append(i)
    return res

【问题讨论】:

  • 这个循环是问题所在:for idx in d[curr-s]:,您可以通过对存储在字典中的索引进行二进制搜索来消除它

标签: arrays algorithm cumulative-sum


【解决方案1】:

我们使用计数字典来跟踪前缀和的计数。我们还将使用大小为 k 的滑动窗口,根据前面的索引增加前缀和的计数,并根据后面的索引减少它。在我们递减之前,我们将根据累积和的计数增加有效子数组的计数,该计数比我们的后累积和多 k。

  def solution(arr, k, s)
    num_subarrays = 0
    front_cumulative_sum = 0
    rear_cumulative_sum = 0
    cumulative_sum_to_count = Hash.new { |h, cumsum| h[cumsum] = 0 }
    0.upto(arr.size - 1 + k) do |front_index|
      front_cumulative_sum += arr[front_index] if front_index <= arr.size - 1
      cumulative_sum_to_count[front_cumulative_sum] += 1 if front_index <= arr.size - 1
      if front_index >= k
        rear_index = front_index - k
        rear_cumulative_sum += arr[rear_index]
        num_subarrays += cumulative_sum_to_count[s + rear_cumulative_sum]
        cumulative_sum_to_count[rear_cumulative_sum] -= 1
      end
    end
    return num_subarrays
  end


> arr = [1,2,4,-1,6,1]
> k=3
> s=6
> solution(arr, k, s)
=> 3

【讨论】:

    猜你喜欢
    • 2021-02-16
    • 1970-01-01
    • 1970-01-01
    • 2020-06-26
    • 2012-10-16
    • 1970-01-01
    • 2019-12-25
    • 1970-01-01
    • 2023-01-25
    相关资源
    最近更新 更多