LeetCode Hot100刷题

560.和为k的子数组

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数

子数组是数组中元素的连续非空序列。

示例 1:

输入:nums = [1,1,1], k = 2
输出:2

示例 2:

输入:nums = [1,2,3], k = 3
输出:2

解题思路:前缀和+哈希表优化

  • 前缀和:前缀和是指从数组开头到当前位置的所有元素的和。例如,数组 [1, 2, 3] 的前缀和数组为 [1, 3, 6]

  • 哈希表:哈希表用于记录某个前缀和出现的次数。通过哈希表,我们可以快速查询是否存在某个前缀和。

核心思想

假设我们有一个前缀和数组 prefixSum,其中 prefixSum[i] 表示从数组开头到第 i 个元素的和。那么,子数组 nums[i..j] 的和可以表示为:

sum(nums[i..j]) = prefixSum[j] - prefixSum[i-1]

如果我们需要找到和为 k 的子数组,那么问题可以转化为:

prefixSum[j] - prefixSum[i-1] = k

即:

prefixSum[j] - k = prefixSum[i-1]

因此,我们只需要在遍历数组时,计算当前的前缀和 prefixSum[j],并检查哈希表中是否存在值为 prefixSum[j] - k 的前缀和。如果存在,说明存在若干子数组的和为 k

class Solution {
    public int subarraySum(int[] nums, int k) {
        // 哈希表用于记录某个前缀和出现的次数
        Map prefixSum = new HashMap<>();
        // 初始化前缀和为0,出现1次
        prefixSum.put(0, 1);
​
        int currentSum = 0; // 当前的前缀和
        int count = 0; // 符合条件的子数组个数
​
        for (int num : nums) {
            currentSum += num; // 更新前缀和
​
            //检查是否存在前缀和为currentSum - k 的情况,存在则累加次数
            if (prefixSum.containsKey(currentSum - k)) {
                count += prefixSum.get(currentSum - k);
            }
            //将前缀和存入哈希表,更新出现次数
            prefixSum.put(currentSum, prefixSum.getOrDefault(currentSum, 0) + 1);
        }
        return count;
    }
}

getOrDefault()方法

在哈希表中,如果我们直接使用 get() 方法获取某个键对应的值,而该键不存在时,get() 会返回 null。如果此时我们尝试对 null 进行数值操作(如加法),就会抛出 NullPointerException 异常。

例如:

Map map = new HashMap<>();
int value = map.get(1); // 如果键 1 不存在,返回 null
value += 1;             // 抛出 NullPointerException

为了避免这种情况,我们可以使用 getOrDefault() 方法。如果键不存在,它会返回一个默认值(通常是 0),而不是 null

在本题的代码中,getOrDefault() 用于更新哈希表中前缀和的出现次数。具体代码如下:

prefixSumCount.put(currentSum, prefixSumCount.getOrDefault(currentSum, 0) + 1);

解释:

  • currentSum:当前的前缀和。

  • prefixSumCount.getOrDefault(currentSum, 0)

    • 如果 currentSum 已经存在于哈希表中,返回其对应的值(即出现次数)。

    • 如果 currentSum 不存在,返回默认值 0

  • + 1:将当前前缀和的出现次数加 1。

  • prefixSumCount.put():将更新后的值存入哈希表。

示例:

假设哈希表当前状态为 {0: 1, 1: 1}currentSum = 2

  • 如果 2 不存在于哈希表中:

    • prefixSumCount.getOrDefault(2, 0) 返回 0

    • 更新后的值为 0 + 1 = 1

    • 哈希表更新为 {0: 1, 1: 1, 2: 1}

  • 如果 2 已经存在于哈希表中(例如 {0: 1, 1: 1, 2: 3}):

    • prefixSumCount.getOrDefault(2, 0) 返回 3

    • 更新后的值为 3 + 1 = 4

    • 哈希表更新为 {0: 1, 1: 1, 2: 4}

你可能感兴趣的:(leetcode,算法,数据结构)