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的子数组

相关推荐
随缘。。。。1 分钟前
web系统安全管理
java
丁一郎学编程9 分钟前
优先级队列(堆)
java·数据结构
Codeking__15 分钟前
前缀和——中心数组下标
数据结构·算法
侧耳倾听11115 分钟前
java集合相关的api-总结
java·开发语言
爱喝热水的呀哈喽26 分钟前
非线性1无修
算法
贺函不是涵28 分钟前
【沉浸式求职学习day43】【Java面试题精选3】
java·开发语言·学习
xiaobin8899934 分钟前
matlab官方免费下载安装超详细教程2025最新matlab安装教程(MATLAB R2024b)
java·开发语言·其他·matlab
花火QWQ1 小时前
图论模板(部分)
c语言·数据结构·c++·算法·图论
小伍_Five1 小时前
spark数据处理练习题详解【下】
java·大数据·spark·scala
Pacify_The_North1 小时前
【进程控制二】进程替换和bash解释器
linux·c语言·开发语言·算法·ubuntu·centos·bash