zoukankan      html  css  js  c++  java
  • 剑指 Offer II 010. 和为 k 的子数组

    给定一个整数数组和一个整数 k ,请找到该数组中和为 k 的连续子数组的个数。

    示例 1 :

    输入:nums = [1,1,1], k = 2
    输出: 2
    解释: 此题 [1,1] 与 [1,1] 为两种不同的情况
    示例 2 :

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

    提示:

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

    来源:力扣(LeetCode)
    链接:https://leetcode-cn.com/problems/QTMn0o
    题解:

    乍一看,以为是滑动窗口的题,直接暴力,但是数据里面有复数,而滑动窗口要求均为整数

    这里要用前缀和+hash map

    时间复杂度过高是因为,使用了一个循环去求解 sum[i] - sum[j - 1] = k 的结果,这个过程消耗的时间复杂度为 O(n)。对 sum[i] - sum[j - 1] = k 做下变形为 sum[j - 1] = sum[i] - k,所以这个循环要找的就是 sum[j - 1] = sum[i] - k 的个数。这个过程使用哈希表就可以将时间复杂度由 O(n) 降为 O(1),因为当前的 sum[i] 是已知计算得到的,而 sum[j - 1] 也只不过是之前计算得到的 sum 而已,若设置哈希表的键为前缀和 sum[i],值为每个和出现的次数,那么就可以做到优化。

    res+=ma[now-k]>0?ma[now-k]:0; //判断前缀差为K 是否存在,存在则加上。不存在加0.
     1 class Solution {
     2 public:
     3     int subarraySum(vector<int>& nums, int k) {
     4         map<int,int> ma;
     5         int n=nums.size(),res=0,now=0;
     6         ma[0]=1;
     7         for(int i=0;i<n;i++)
     8         { 
     9             now+=nums[i];
    10             res+=ma[now-k]>0?ma[now-k]:0;//用于找是否存在前缀和的差是k的数
    11             ma[now]>0?ma[now]++:ma[now]=1; //存前缀和
    12         }
    13         return res;
    14     }
    15 };
  • 相关阅读:
    DataGridView 实现,折叠的Tree效果
    DEV 总结
    EWS:邮箱的一个开放的接口服务
    socket,模拟服务器、客户端通信
    在ASP.NET Core中构建路由的5种方法
    扩展方法、泛型、委托,的小案例
    操作Work、Excel、PDF
    d3实现家族树
    大数据时代的图表可视化利器——highcharts,D3和百度的echarts
    函数防抖与节流
  • 原文地址:https://www.cnblogs.com/sylvia1111/p/15715951.html
Copyright © 2011-2022 走看看