leetcode
leetcode 2901 ~ 2950
和为 K 的子数组

和为 K 的子数组

难度:

标签:

题目描述

English description is not available for the problem. Please switch to Chinese.

代码结果

运行时间: 48 ms, 内存: 18.7 MB


/*
 * 思路:
 * 虽然Java Stream不适合处理这种涉及前缀和和哈希表的复杂逻辑,
 * 但我们可以通过转换Stream来实现主要逻辑。
 */
import java.util.HashMap;
import java.util.stream.IntStream;

public class SubarraySumEqualsKStream {
    public int subarraySum(int[] nums, int k) {
        HashMap<Integer, Integer> prefixSumCount = new HashMap<>();
        prefixSumCount.put(0, 1);  // 初始前缀和为0,出现一次
        int[] sum = {0};
        int[] count = {0};

        IntStream.of(nums).forEach(num -> {
            sum[0] += num;
            if (prefixSumCount.containsKey(sum[0] - k)) {
                count[0] += prefixSumCount.get(sum[0] - k);
            }
            prefixSumCount.put(sum[0], prefixSumCount.getOrDefault(sum[0], 0) + 1);
        });

        return count[0];
    }
}

解释

方法:

本题解使用了前缀和与哈希表的组合策略。首先,定义一个变量 `cur_sum` 来存储从数组开始到当前元素的连续子数组的和。使用一个哈希表 `pre_dict` 来记录所有可能的前缀和的出现次数,其中键是前缀和,值是该前缀和出现的次数。在遍历数组的每个元素时,更新 `cur_sum`。接下来,检查 `cur_sum - k` 是否存在于 `pre_dict` 中,如果存在,表示找到了一个和为 `k` 的子数组,其次数为 `pre_dict[cur_sum - k]`。然后,更新哈希表,增加当前 `cur_sum` 的计数。这种方法能够有效地在一次遍历中计算出和为 `k` 的子数组的数量。

时间复杂度:

O(n)

空间复杂度:

O(n)

代码细节讲解

🦆
在题解中,为什么要使用前缀和而不是直接遍历数组计算子数组的和?
使用前缀和的主要原因是效率。如果直接遍历数组来计算每个可能的子数组的和,这种方法的时间复杂度会是O(n^2),因为对于数组中的每个元素,你可能都需要遍历后续的所有元素来计算子数组的和。相比之下,前缀和方法可以将这个问题简化为O(n)复杂度。通过使用前缀和,我们可以快速计算任何子数组的和,因为子数组 `sum(i, j)` 可以通过 `prefixSum[j] - prefixSum[i-1]` 得到,这使得算法更加高效。
🦆
哈希表 `pre_dict` 初始时为什么要设置 `{0: 1}`,这代表了什么意义?
在哈希表 `pre_dict` 中设置 `{0: 1}` 的意义在于,它代表了一个虚拟的前缀和,即在数组的开始之前,已经有一个和为0的前缀和出现了1次。这样做的主要目的是为了正确处理那些从数组第一个元素开始的子数组,其和恰好为k的情况。如果没有将0初始化在哈希表中,那么当遇到累积和恰好等于k的情况时,我们无法记录这是一个有效的子数组,因为没有0作为参照。
🦆
在更新哈希表时,为什么要检查 `cur_sum - k` 而不是其他值?这与前缀和的计算有何关联?
检查 `cur_sum - k` 是为了找出是否存在一个子数组的和正好等于k。这是基于前缀和的性质:如果两个前缀和之差等于k(即 `prefixSum[j] - prefixSum[i] = k`),那么从索引 `i+1` 到 `j` 的子数组和就是k。在这里,`cur_sum` 代表到当前元素为止的前缀和,通过查询 `cur_sum - k` 是否存在于哈希表中,我们实际上是在查找是否有一个之前的前缀和,使得从那个点到当前点的子数组和刚好为k。这是一种有效检测子数组和为k的方法,而且通过哈希表的帮助,这种检查可以非常迅速地完成。

相关问题