LeetCode Hot100(9/100)—— 560. 和为 K 的子数组

文章目录

一、题目描述

题目链接:LeetCode - Subarray Sum Equals K

题意:

给定一个整数数组 nums 和一个整数 k,请你找出数组中 和等于 k 的子数组的个数


示例:

复制代码
输入:nums = [1,1,1], k = 2
输出:2
解释:子数组 [1,1] 有两个 ------ 第一个与第二个元素组成、第二个与第三个元素组成。

二、解题思路总览

Subarray Sum Equals K
暴力枚举
计算所有子数组的和
n^2
前缀和优化
用 prefix[i] 表示前 i 个元素的和
通过 prefix[j]-prefix[i] 判断子数组和
时间复杂度 O(n^2),空间 O(n)
哈希表优化
利用 Map 记录前缀和出现次数
prefixSum - k 能找到匹配数
时间复杂度 O(n),空间 O(n)


三、解法一:暴力枚举法

核心思想:

穷举所有可能的子数组 [i, j],计算它们的和,若等于 k,计入答案。

思路流程图



开始
初始化 count = 0
遍历 i 从 0 到 n-1
初始化 sum = 0
遍历 j 从 i 到 n-1
累加 sum += nums[j]
sum == k ?
计数 count++
继续 j++
输出 count
结束

Java 代码实现

java 复制代码
public class SubarraySumEqualsK {
    public int subarraySum(int[] nums, int k) {
        int count = 0;
        for (int i = 0; i < nums.length; i++) {
            int sum = 0;
            for (int j = i; j < nums.length; j++) {
                sum += nums[j];
                if (sum == k) {
                    count++;
                }
            }
        }
        return count;
    }
}

复杂度分析

  • 时间复杂度:O(n²)
  • 空间复杂度:O(1)

四、解法二:前缀和优化版

核心思想:

创建一个前缀和数组 prefixSum[i] 表示从开头到第 i 个元素的累积和。

子数组 [i, j] 的和即为 prefixSum[j] - prefixSum[i-1]

步骤示意图

nums: [1,2,3]
prefix[0]=0
prefix[1]=1
prefix[2]=3
prefix[3]=6
计算 prefix[j]-prefix[i]

Java 代码实现

java 复制代码
public class SubarraySumEqualsK {
    public int subarraySum(int[] nums, int k) {
        int n = nums.length;
        int[] prefix = new int[n + 1];
        int count = 0;

        for (int i = 1; i <= n; i++) {
            prefix[i] = prefix[i - 1] + nums[i - 1];
        }

        for (int i = 0; i < n; i++) {
            for (int j = i + 1; j <= n; j++) {
                if (prefix[j] - prefix[i] == k) {
                    count++;
                }
            }
        }
        return count;
    }
}

复杂度分析

  • 时间复杂度:O(n²)
  • 空间复杂度:O(n)

五、解法三:前缀和 + 哈希表优化版(最优解)

核心思想:

在遍历数组时,用一个哈希表记录"前缀和出现的次数"。

当我们计算出当前 prefixSum 后,如果存在 prefixSum - k 的记录,说明之前有一个前缀和使得当前这段子数组的和为 k

思维导图

哈希表优化
当前前缀和 prefixSum
查找 prefixSum - k 是否存在
若存在,对应次数累加到结果
更新哈希表中 prefixSum 出现次数

流程演示

假设 nums = [1, 2, 3], k = 3

步骤 当前数字 prefixSum prefixSum-k HashMap状态 count结果
1 1 1 -2 {0:1,1:1} 0
2 2 3 0 {0:1,1:1,3:1} 1(找到1次)
3 3 6 3 {0:1,1:1,3:1,6:1} 2(再找到一次)

Java 代码实现

java 复制代码
import java.util.HashMap;
import java.util.Map;

public class SubarraySumEqualsK {
    public int subarraySum(int[] nums, int k) {
        Map<Integer, Integer> prefixCount = new HashMap<>();
        prefixCount.put(0, 1); // 初始前缀和为 0
        int prefixSum = 0;
        int count = 0;

        for (int num : nums) {
            prefixSum += num;
            if (prefixCount.containsKey(prefixSum - k)) {
                count += prefixCount.get(prefixSum - k);
            }
            prefixCount.put(prefixSum, prefixCount.getOrDefault(prefixSum, 0) + 1);
        }

        return count;
    }
}

复杂度分析

  • 时间复杂度:O(n)
  • 空间复杂度:O(n)

总结

解法类型 时间复杂度 空间复杂度 适用场景
暴力枚举 O(n²) O(1) 数据规模较小
前缀和优化 O(n²) O(n) 理解前缀和概念
哈希表优化 O(n) O(n) 最优解法,适合大规模数据
相关推荐
心中有国也有家4 小时前
cann-recipes-infer:昇腾 NPU 推理的“菜谱集合”
经验分享·笔记·学习·算法
绝知此事4 小时前
【算法突围 01】线性结构与哈希表:后端开发的收纳术
java·数据结构·算法·面试·jdk·散列表
碧海银沙音频科技研究院4 小时前
通话AEC与语音识别AEC的软硬回采链路
深度学习·算法·语音识别
csdn_aspnet5 小时前
Python 算法快闪 LeetCode 编号 70 - 爬楼梯
python·算法·leetcode·职场和发展
LuminousCPP5 小时前
数据结构 - 线性表第四篇:C 语言通讯录优化升级全记录(踩坑 + 思考)
c语言·开发语言·数据结构·经验分享·笔记·学习
AI算法沐枫6 小时前
深度学习python代码处理科研测序数据
数据结构·人工智能·python·深度学习·决策树·机器学习·线性回归
m0_629494737 小时前
LeetCode 热题 100-----26.环形链表 II
数据结构·算法·leetcode·链表
壹号用户8 小时前
用队列实现栈
数据结构·算法
做人求其滴8 小时前
面试经典 150 题 380 274
c++·算法·面试·职场和发展·力扣