LeetCode LCR 010 和为 K 的子数组 (Java)

两种解法详解:暴力枚举与前缀和+哈希表寻找和为k的子数组

在解决数组中和为k的连续子数组个数的问题时,我们可以采用不同的方法。本文将详细解析两种常见的解法:暴力枚举法和前缀和结合哈希表的方法,分析它们的思路、优缺点及适用场景。


问题描述

给定一个整数数组 nums 和一个整数 k,要求找到所有和为 k 的连续子数组的个数。

示例

复制代码
输入:nums = [1,1,1], k = 2
输出:2
解释:[1,1](前两个元素)和 [1,1](后两个元素)各为一种情况。

解法一:暴力枚举法

思路分析

暴力枚举法的核心思想是遍历所有可能的子数组,计算它们的和是否等于 k。具体来说:

  • 外层循环固定子数组的起始位置 start
  • 内层循环从 start 出发,逐步扩展子数组的结束位置 j,并累加元素和。
  • 当子数组和等于 k 时,计数器增加。

代码实现

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

复杂度分析

  • 时间复杂度 :O(n²)。双重循环遍历所有子数组,对于长度为 n 的数组,共有 n(n+1)/2 个子数组。
  • 空间复杂度:O(1)。仅使用常数空间存储临时变量。

适用场景

适用于小规模数据(例如 n ≤ 1e3)。当 n 较大时(如 n = 2e4),暴力法会因时间复杂度过高而超时。


解法二:前缀和 + 哈希表

思路分析

该方法利用前缀和的性质和哈希表的快速查询特性,将时间复杂度优化至线性:

  1. 前缀和定义sum[i] 表示数组前 i 个元素的和。
  2. 关键观察 :若存在 sum[j] - sum[i] = k,则子数组 nums[i+1..j] 的和为 k
  3. 哈希表优化 :维护哈希表记录前缀和出现的次数。遍历时,若当前前缀和 sumsum - k 存在,则累加次数。

代码实现

java 复制代码
    public static int subarraySum_2(int[] nums, int k) {
        int count=0;    //记录结果
        int sum = 0;    //记录前缀和

        //HashMap,k:存储前缀和,V:存储前缀和出现的次数
        HashMap<Integer, Integer> map = new HashMap<>();

        //第一个数的前缀和为0
        map.put(0,1);

        for(int i=0;i<nums.length;i++){
            sum +=nums[i];

            //注意这一定是先去判断再添加,每个数都要去判断一下,第一个数的前缀和已经添加了,所以需要判断
            if(map.containsKey(sum-k)){
                count += map.get(sum-k);
            }

            //如何这个sum没出现过:v = 0+1,出现过:v = 原来v + 1;
            map.put(sum,map.getOrDefault(sum,0)+1);
        }
        return count;
    }

复杂度分析

  • 时间复杂度:O(n)。只需一次遍历数组,哈希表查询和插入操作均为 O(1)。
  • 空间复杂度 :O(n)。哈希表最多存储 n 个不同的前缀和。

关键点

  • 哈希表初始化 :预先放入 (0, 1),处理以第一个元素开头的子数组和为 k 的情况。
  • 负数处理:数组中可能存在负数,导致前缀和重复出现,哈希表需正确统计次数。

方法对比

方法 时间复杂度 空间复杂度 适用场景
暴力枚举法 O(n²) O(1) 小规模数据
前缀和 + 哈希表法 O(n) O(n) 大规模数据

总结

  • 暴力枚举法思路简单,但仅适用于小规模数据。
  • 前缀和+哈希表通过空间换时间,将复杂度降至线性,是处理大规模数据的高效方法。
  • 特别注意哈希表的初始化与更新逻辑,确保正确处理所有边界情况。

相关题目LeetCode 560. 和为K的子数组

相关推荐
Kali_077 分钟前
使用 Mathematical_Expression 从零开始实现数学题目的作答小游戏【可复制代码】
java·人工智能·免费
贾全13 分钟前
第十章:HIL-SERL 真实机器人训练实战
人工智能·深度学习·算法·机器学习·机器人
rzl0219 分钟前
java web5(黑马)
java·开发语言·前端
GIS小天28 分钟前
AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年7月4日第128弹
人工智能·算法·机器学习·彩票
guojl38 分钟前
深度解读jdk8 HashMap设计与源码
java
guojl44 分钟前
深度解读jdk8 ConcurrentHashMap设计与源码
java
满分观察网友z1 小时前
开发者的“右”眼:一个树问题如何拯救我的UI设计(199. 二叉树的右视图)
算法
爱上语文1 小时前
Redis基础(5):Redis的Java客户端
java·开发语言·数据库·redis·后端
A~taoker1 小时前
taoker的项目维护(ng服务器)
java·开发语言
HGW6891 小时前
基于 Elasticsearch 实现地图点聚合
java·elasticsearch·高德地图