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

相关推荐
熊文豪5 分钟前
探索CANN ops-nn:高性能哈希算子技术解读
算法·哈希算法·cann
熊猫_豆豆22 分钟前
YOLOP车道检测
人工智能·python·算法
rannn_11122 分钟前
【苍穹外卖|Day4】套餐页面开发(新增套餐、分页查询、删除套餐、修改套餐、起售停售)
java·spring boot·后端·学习
qq_124987075326 分钟前
基于JavaWeb的大学生房屋租赁系统(源码+论文+部署+安装)
java·数据库·人工智能·spring boot·计算机视觉·毕业设计·计算机毕业设计
短剑重铸之日32 分钟前
《设计模式》第十一篇:总结
java·后端·设计模式·总结
艾莉丝努力练剑36 分钟前
【Linux:文件】Ext系列文件系统(初阶)
大数据·linux·运维·服务器·c++·人工智能·算法
若鱼19191 小时前
SpringBoot4.0新特性-Observability让生产环境更易于观测
java·spring
觉醒大王1 小时前
强女思维:着急,是贪欲外显的相。
java·论文阅读·笔记·深度学习·学习·自然语言处理·学习方法
偷吃的耗子1 小时前
【CNN算法理解】:CNN平移不变性详解:数学原理与实例
人工智能·算法·cnn
努力学编程呀(๑•ี_เ•ี๑)1 小时前
【在 IntelliJ IDEA 中切换项目 JDK 版本】
java·开发语言·intellij-idea