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

LeetCode——560. 和为 K 的子数组

[560. 和为 K 的子数组]

      • 分析:
      • 正确的解法:前缀和 + 哈希表

(https://leetcode.cn/problems/subarray-sum-equals-k/)

已解答

中等

相关标签

相关企业

提示

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

分析:

没注意到要连续,好吧,我当成了背包问题。。。。附上代码(错误版本)

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        //vector<vector<int>> dp(nums.size(),0);
        vector<vector<int>> dp(nums.size(), vector<int>(k+1, 0));
        for(int i=0;i<=k;i++){
            if(nums[0]==i)
                dp[0][i]=1;
        }
        for(int i=0;i<nums.size();i++){
            dp[i][0]=1;
        }
        dp[0][0]=1;
        for(int i=1;i<nums.size();i++){
            for(int j=1;j<=k;j++){
               if(j-nums[i]>=0)
                dp[i][j]=dp[i-1][j]+dp[i-1][j-nums[i]];
               
               else
                    dp[i][j]=dp[i-1][j];
            }
        }
        return dp[nums.size()-1][k];
    }
};

方法又用错了,滑动窗口方法无法用于包含负数的队列。解答错误35 / 93 个通过的测试用例,提交于 2025.03.12 09:32

class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        if(nums.size()==0)
            return 0;
        int i=0,j=1;
        int sum=nums[0];
        int ans=0;
        if(nums.size()==1&&sum==k){
            return 1;
        }
        while(i<nums.size()&&j<nums.size()){
            if(sum<k){
                sum+=nums[j];
                j++;
            }
            if(sum==k){
                ans++;
                sum-=nums[i];
                i++;
            }
            if(sum>k){
                sum-=nums[i];
                i++;
            }
            if(sum==k){
                ans++;
                sum-=nums[i];
                i++;
            }

        }
        while(i<nums.size()){
            if(sum==k){
                ans++;
            }
            sum-=nums[i];
            i++;
        }
        return ans;
    }
};

等于是,正数的样例被我通过了,带有负数的样例,没通过。

这个问题不能使用滑动窗口,因为 nums 可能包含负数,导致窗口无法通过简单的收缩/扩展来找到正确的子数组。

例如,[1, -1, 1],如果 k=1,滑动窗口会错误地跳过某些子数组。

正确的解法:前缀和 + 哈希表

我们可以用 前缀和 + 哈希表 来高效解决这个问题。

思路:

  • 维护一个 prefixSum(表示从数组起点到当前索引的和)。
  • 使用 unordered_map<int, int> 记录前缀和出现的次数。
  • 计算当前 prefixSum 时,检查 prefixSum - k 是否存在于哈希表中,若存在,则说明前面某一段子数组的和为 k,增加计数。
  • prefixSum 存入哈希表,以便后续计算。

说明:

  1. prefixSum[i] = nums[0] + nums[1] + ... + nums[i], prefixSum[i] 代表从 0 到 i 位置的 累积和。
  2. 任何子数组 nums[l] ... nums[r] 的和等于:`sum = prefixSum[r] - prefixSum[l-1]``
  3. ``prefixSum[r] - k == prefixSum[l-1]。说明 如果我们在前面某个位置 l-1 计算过 prefixSum[l-1],那么 prefixSum[r] - k应该等于prefixSum[l-1]`,这就意味着找到了一个和为 k 的子数组。
  4. 假设 prefixSum - k 之前出现了 多次,那么说明有 多个子数组 的和等于 k,我们需要把这些子数组全部计入答案。所以prefixSumCount 需要存次数,而不是简单存前缀和
class Solution {
public:
    int subarraySum(vector<int>& nums, int k) {
        unordered_map<int,int> preSumCount;
        preSumCount[0]=1;
        int preSum=0;
        int ans=0;
        for(auto& num:nums){
            preSum+=num;
            if(preSumCount.find(preSum-k)!=preSumCount.end()){
                ans+=preSumCount[preSum-k];
            }
            preSumCount[preSum]++;
        }
        return ans;
    }
};

相关文章:

  • 目前人工智能的发展,判断10年、20年后的人工智能发展的主要方向,或者带动的主要产业
  • 【openwebui 搭建本地知识库(RAG搭建本地知识库)】
  • 软件测试之测试用例
  • Microsoft Edge “无法更新” 解决办法
  • 学习笔记之车票搜索为什么用Redis而不是ES?
  • 32单片机——LED
  • 通过 Python 爬虫提高股票选股胜率
  • 【教学类-43-26】20240312 数独4宫格的所有可能(图片版 576套样式,空1格-空8格,每套65534张*576小图=3千万张小图)
  • 【web】网页崩溃
  • 【初级篇】如何使用DeepSeek和Dify构建高效的企业级智能客服系统
  • SVT-AV1源码分析函数 svt_av1_cost_coeffs_txb
  • 【Python入门】一篇掌握Python中的字典(创建、访问、修改、字典方法)【详细版】
  • Python使用FastAPI结合Word2vec来向量化200维的语言向量数值
  • Python爬取房天下二手小区数据(2025年3月更)
  • 布达佩斯召开 | 2025年第五届能源与环境工程国际会议(CoEEE 2025)
  • SpringBoot中使用kaptcha生成验证码
  • Spring 中 BeanPostProcessor 的作用和示例
  • Facebook投广告支付操作
  • 04 1个路由器配置一个子网的dhcp服务
  • 电脑实用小工具--VMware常用功能简介
  • 福州做网站的公司多少钱/互联网舆情监测系统
  • 网站做支付接口/网站排名查询软件
  • 北京微信网站建设报价单/seo系统培训哪家好
  • 网站靠什么/制作网站建设入门
  • 给新公司建网站/seo优化培训
  • .net和php那个做网站好/上海百度推广优化公司