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

和为 K 的子数组-leetcode

题目描述

给你一个整数数组 nums 和一个整数 k ,请你统计并返回 该数组中和为 k 的子数组的个数

子数组是数组中元素的连续非空序列。

示例 1:

输入:nums = [1,1,1], k = 2
输出:2

示例 2:

输入:nums = [1,2,3], k = 3
输出:2

提示:

  • 1 <= nums.length <= 2 * 104
  • -1000 <= nums[i] <= 1000
  • -107 <= k <= 107

解法一

思路:

枚举算法,从下标i开始,统计后面所有位置的字串和,当中若出现和为k则个数加一

代码:

public class leetcode_010 {public static int subarraySum(int[] nums, int k) {int ans=0;int tempSum=0;for(int i=0;i<nums.length;i++){tempSum+=nums[i];if(tempSum==k)ans++;for (int j=i+1;j<nums.length;j++){tempSum+=nums[j];if(tempSum==k)ans++;}tempSum=0;}return ans;}public static void main(String[] args) {Scanner sc = new Scanner(System.in);String[] line = sc.nextLine().split(",");int[] nums= Arrays.stream(line).mapToInt(Integer::parseInt).toArray();int k = sc.nextInt();int res = subarraySum(nums,k);System.out.println(res);}
}

解法二

思路:

来自官方的解答,采用前缀和和哈希表进行优化,时间复杂度为O(n)。

  • 前缀和(Prefix Sum):定义 pre[i] 为数组从索引 0i 的所有元素之和。例如,对于数组 numspre[i] = nums[0] + nums[1] + ... + nums[i]
  • 子数组和:子数组 [j..i] 的和可以表示为 pre[i] - pre[j-1]。注意,当 j=0 时,pre[j-1] 定义为 0(即没有元素时的前缀和)。
  • 目标条件:我们想找到所有满足 pre[i] - pre[j-1] == k 的子数组。这等价于 pre[j-1] == pre[i] - k。因此,对于每个 i,我们需要统计有多少个 j(其中 j0i)使得 pre[j-1] 等于 pre[i] - k

为了高效地统计这些 j 的个数,我们使用一个哈希表(如 HashMap),键是前缀和的值,值是该前缀和出现的次数。这样,对于每个 i,我们可以直接在哈希表中查找 pre[i] - k 的出现次数,从而避免重复计算。

步骤详解

  1. 初始化
    • 创建一个哈希表 map,用于存储前缀和及其出现次数。
    • 初始时,放入前缀和 0,出现次数为 1。这是因为当没有元素时,前缀和为 0,且这相当于 j=0 时的 pre[j-1] = 0
    • 初始化当前前缀和 pre = 0 和计数器 count = 0
  2. 遍历数组
    • 对于每个元素 nums[i]
      • 更新当前前缀和:pre = pre + nums[i]
      • 计算目标值 target = pre - k。这个目标值就是我们要在哈希表中查找的 pre[j-1]
      • 如果 target 存在于哈希表中,则说明存在若干下标 j(对应 pre[j-1] = target),使得子数组 [j..i] 的和为 k。因此,将 count 加上 map.get(target)
      • 将当前前缀和 pre 加入哈希表:如果 pre 已存在,则将其出现次数加 1;否则,放入 pre 并设置次数为 1
  3. 返回结果
    • 遍历结束后,count 即为所有和为 k 的连续子数组的个数。

遍历的过程中,我们先求出前缀和,当下标来到i时,我们求pre[i]-k出现的次数,即需要统计有多少个 j(其中 j0i)使得 pre[j-1] 等于 pre[i] - k。这些前缀和在我们求pre[i]前就已经求出。

为什么pre[i] - k出现的次数等于多少个j,因为我们从头开始求前缀和,[0i]只会统计一次,当出现相同的前缀和时,是不用的[0i]计算得来的。

代码:

public class Solution {public int subarraySum(int[] nums, int k) {int count = 0, pre = 0;HashMap < Integer, Integer > mp = new HashMap < > ();mp.put(0, 1);for (int i = 0; i < nums.length; i++) {pre += nums[i];if (mp.containsKey(pre - k)) {count += mp.get(pre - k);}mp.put(pre, mp.getOrDefault(pre, 0) + 1);//若当前前缀和不存在,则创建该前缀和,出现次数置为1,若出现过这个前缀和,则该前缀和出现的次数加1}return count;}
}
http://www.zskr.cn/news/3862.html

相关文章:

  • 《10人以下小团队管理手册》读后感
  • GZHOIOJ律(一)
  • Kali Linux 虚拟机安装(VMware Workstation 17)
  • lilctf 部分wp - Elma
  • Selenium应用中的核心JavaScript操作技巧
  • 双重map 的赋值初始化
  • 0voice-1.4.1
  • AI踩坑之Nlog使用
  • 论文解读-《OpenGSL A Comprehensive Benchmark for Graph Structure Learning》 - zhang
  • Git 生成 ssh key
  • 一生一芯学习:pa2.1 RTFM
  • 一行代码没写,做了一个小程序
  • copyparty 是一款使用单个 Python 材料实现的内网文件共享软件,具有跨平台、低资源占用等特点,适合需要本地化文件管理的场景
  • 电商系统的Mysql表设计是怎么样呢
  • Docker应用 - CloudSaver
  • Web 3
  • Cursor小程序实战系列一:0到1开发一个小程序,需求整理、小程序注册备案
  • 赛题
  • .gitignore 文件
  • MySQL集群高可用架构 - 指南
  • 在Kubernetes中DaemonSet无法在master节点调度的问题
  • 9 12-
  • 在CentOS 7系统中彻底移除MongoDB数据库
  • 【数学建模】烟幕干扰弹投放策略优化:模型与算法整合框架 - 实践
  • 开源排名算法工具raink:利用LLM实现智能文档排序
  • Metasploit Framework 6.4.88 (macOS, Linux, Windows) - 开源渗透测试框架
  • 中大型水闸安全监测的重要性及实施方法 - 指南
  • python 轻量级别的网页包Streamlit
  • 大模型基础|位置编码|RoPE|ALiBi
  • grafana部署并使用harbor监控模板