前缀和(5)_和为k的子数组

个人主页:C++忠实粉丝
欢迎 点赞👍 收藏✨ 留言✉ 加关注💓本文由 C++忠实粉丝 原创

前缀和(5)_和为k的子数组

收录于专栏【经典算法练习
本专栏旨在分享学习算法的一点学习笔记,欢迎大家在评论区交流讨论💌

目录

1. 题目链接 :

2. 题目描述 :

3. 解法(一维前缀和) :

    算法思路 :

    代码展示 :

    结果分析 :


1. 题目链接 :

OJ链接: 和为k的子数组

2. 题目描述 :

给你一个整数数组 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

3. 解法(一维前缀和) :

    算法思路 :

设i为数组中的任意位置,用sum[i]表示[0,i]区间内所有元素的和.

想知道有多少个[以i为结尾的和为k的子数组],就要找到有多少个起始位置x1, x2, x3...使得[x, i]区间内的所有元素的和为k.那么[0, x]区间内的和是不是就是sum[i] - k了.于是问题就变成:

        找到[0, i - 1]区间内,有多少前缀和等于sum[i] - k的即可

我们不用真的初始化一个前缀和数组,因为我们只关心在i位置之前,有多少个前缀和等于sum[i - k]因此,我们仅需用一个哈希表,一边求当前位置的前缀和,一边存下之前每一种前缀和出现的次数.

    代码展示 :

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        unordered_map <int, int> hash;
        //sum == k时的情况
        hash[0] = 1;
        int ret = 0, sum = 0;

        for(auto x : nums)
        {
            sum += x;//计算前缀和
            if(hash.count(sum - k)) ret += hash[sum - k];//统计个数
            hash[sum]++;
        }
        return ret;
    }
};

以i位置结尾的所有的子数组.在[0,i - 1]区间内,有多少个前缀和等于sum[i] - k 

 

    结果分析 :

 注意细节问题:

1. 前缀和加入哈希表的时机:

        在计算i位置之前,哈希表里面只保存[0, i - 1]位置的前缀和

2. 不用真的创建一个前缀和数组

        用一个变量sum来标记前一个位置的前缀和即可

3. 如果整个前缀和等于k:

        hash[0] = 1;

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值