当前位置: 首页 > news >正文

【LeetCode 热题 100】(四)子串

560. 和为k的子数组

class Solution {public int subarraySum(int[] nums, int k) {// 1.定义全局总个数int count = 0;int pre = 0;HashMap<Integer, Integer> map = new HashMap<>();map.put(0,1);for (int i = 0; i < nums.length; i++) {pre = pre + nums[i];if(map.containsKey(pre - k)){count = count + map.get(pre-k);}map.put(pre, map.getOrDefault(pre,0) + 1);}return count;}
}

解题思路:前缀和 + 哈希表(统计和为K的子数组数量)

核心思想

使用前缀和技巧配合哈希表高效统计连续子数组的和等于目标值 k 的数量,避免暴力解法的O(n²)时间复杂度。

关键概念
  1. 前缀和 pre

    • 表示从数组起始位置到当前位置的所有元素之和
    • pre = nums[0] + nums[1] + ... + nums[i]
  2. 子数组和与k的关系

    • 子数组 [j, i] 的和 = pre[i] - pre[j-1]
    • 当子数组和等于 k 时:pre[i] - pre[j-1] = k
    • 变形为:pre[j-1] = pre[i] - k
算法步骤
  1. 初始化

    int count = 0;          // 统计满足条件的子数组数量
    int pre = 0;            // 当前前缀和(初始为0)
    HashMap<Integer, Integer> map = new HashMap<>();
    map.put(0, 1);          // 关键:前缀和为0的情况出现1次(空数组)
    
  2. 遍历数组

    for (int i = 0; i < nums.length; i++) {// 更新前缀和pre += nums[i];// 检查是否存在 pre_j = pre - kif (map.containsKey(pre - k)) {count += map.get(pre - k);  // 累加符合条件的子数组数量}// 记录当前前缀和出现次数map.put(pre, map.getOrDefault(pre, 0) + 1);
    }
    
执行流程(以 nums=[1,1,1], k=2 为例)
inums[i]prepre-k检查 mapcountmap 更新
0111-2=-10{0:1, 1:1}
1122-2=0存在0:11{0:1, 1:1, 2:1}
2133-2=1存在1:12{0:1, 1:1, 2:1, 3:1}
关键点解析
  1. 为什么需要 map.put(0,1)

    • 处理子数组从索引0开始的情况
    • pre == k 时,pre-k=0 能在map中找到
  2. 哈希表的作用

    • key:前缀和的值
    • value:该前缀和出现的次数
    • 通过 pre-k 快速查找符合条件的子数组起点数量
  3. 时间复杂度 O(n)

    • 只需遍历数组一次
    • 哈希表操作O(1)时间复杂度
示例说明
  • 输入nums = [1,1,1], k=2
  • 有效子数组
    1. [1,1](索引0-1):1+1=2
    2. [1,1](索引1-2):1+1=2
  • 输出count = 2
算法优势
  1. 高效:相比暴力解法(O(n²)),优化到O(n)
  2. 通用:处理正负数混合数组(哈希表不依赖元素顺序)
  3. 简洁:仅需单次遍历+常数空间(哈希表大小与数据规模无关)
扩展应用

此方法可解决类似问题:

  • 统计子数组和等于k的最小长度
  • 寻找和为k的最长子数组
  • 处理乘积等其他运算的变种问题
http://www.xdnf.cn/news/1231453.html

相关文章:

  • 前端-移动Web-day3
  • 云环境K8s集群WebSocket连接失败解决方案
  • 【REACT18.x】使用vite创建的项目无法启动,报错TypeError: crypto.hash is not a function解决方法
  • 基于 LightGBM 的二手车价格预测
  • GaussDB having 的用法
  • 图像加密学习日志————论文学习DAY4
  • 分布式事务----spring操作多个数据库,事务以及事务回滚还有用吗
  • 机械臂的轨迹生成的多种方案
  • Jupyter notebook如何显示行号?
  • MFC 实现托盘图标菜单图标功能
  • NCV8402ASTT1G自保护N沟道功率MOSFET安森美/ONSEMI 过流过温保护汽车级驱动NCV8402ASTT1
  • 从基础功能到自主决策, Agent 开发进阶路怎么走?
  • 【计算机网络】Socket网络编程
  • Android 15 限制APK包手动安装但不限制自升级的实现方案
  • 断路器瞬时跳闸曲线数据获取方式
  • Javaweb————Apache Tomcat服务器介绍及Windows,Linux,MAC三种系统搭建Apache Tomcat
  • 嵌入式第十八课!!数据结构篇入门及单向链表
  • Oracle 11gR2 Clusterware应知应会
  • IDM下载失败排查
  • 704. 二分查找
  • 市政污水厂变频器联网改造方案-profibus转ethernet ip网关(通俗版)
  • CommonJS和ES6 Modules区别
  • python:以支持向量机(SVM)为例,通过调整正则化参数C和核函数类型来控制欠拟合和过拟合
  • Autosar Nm-网管报文PNC停发后无法休眠问题排查
  • 区分「尊重」和「顺从」
  • 简化理解I2C总线
  • Android13文件管理USB音乐无专辑图片显示的是同目录其他图片
  • 【Django】-6- 登录用户身份鉴权
  • Piriority_queue
  • Java多线程入门-基础概念与线程操作