• 【LeetCode】Day108-和为 K 的子数组


    题目

    560. 和为 K 的子数组【中等】

    题解

    枚举法

    实际上就是暴力计算,双重循环

    class Solution {
        public int subarraySum(int[] nums, int k) {
            int n=nums.length;
            int count=0;
            for(int i=0;i<n;i++){
                int sum=0;
                for(int j=i;j<n;j++){
                    sum+=nums[j];
                    if(sum==k)
                        count++;
                }
            }
            return count;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    时间复杂度: O ( n 2 ) O(n^2) O(n2)

    空间复杂度: O ( 1 ) O(1) O(1)

    前缀和+哈希表

    这个逻辑非常的妙

    首先,基于方法一,对于每一个 i ,我们都要枚举 j 来判断是否符合条件,这个过程是否可以用数据结构精简呢?
    我们定义 pre[i] 为 [0…i] 里所有数的和,则 pre[i] 可以由 pre[i−1] 递推而来,即 p r e [ i ] = p r e [ i − 1 ] + n u m s [ i ] pre[i]=pre[i−1]+nums[i] pre[i]=pre[i1]+nums[i]
    那么「[j…i] 这个子数组和为 k 」这个条件我们可以转化为 p r e [ i ] − p r e [ j − 1 ] = = k , pre[i]−pre[j−1]==k, pre[i]pre[j1]==k再进行简单移项,得到 p r e [ j − 1 ] = = p r e [ i ] − k pre[j−1]==pre[i]−k pre[j1]==pre[i]k
    所以我们考虑 i 有多少个前缀和为 pre[i]−k 的 pre[j] 即可。

    其次,建立哈希表mp,以 和-次数 为键值对,记录 pre[i] 出现的次数,从左往右边更新 mp 边计算答案,那么以 i 结尾的答案 mp[pre[i]−k] 即可在 O(1) 时间内得到

    进一步优化,由于pre[i]只和pre[i-1]有关,因此可以不用建立pre数组,直接用变量pre来记录答案。

    class Solution {
        public int subarraySum(int[] nums, int k) {
            int n=nums.length;
            int pre=0,count=0;
            Map<Integer,Integer>mp=new HashMap<>();
            mp.put(0,1);//0->i前缀和数组 恰好为k的情况,做一个初始化
            for(int i=0;i<n;i++){
                pre+=nums[i];
                if(mp.containsKey(pre-k))
                    count+=mp.get(pre-k);
                mp.put(pre,mp.getOrDefault(pre,0)+1);
            }
            return count;
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15

    时间复杂度: O ( n ) O(n) O(n)

    空间复杂度: O ( n ) O(n) O(n)

  • 相关阅读:
    golang中常用的定义map的两种方法
    【生信分析】基于TCGA肿瘤数据进行基因共表达网络分析
    2022年武汉专精特新小巨人企业奖励补贴以及申报条件汇总
    postgresql
    6 个意想不到的 JavaScript 问题
    场景应用:图解扫码登录流程
    代理模式-静态动态代理-jdk动态代理-cglib动态代理
    人机验证reCAPTCHA v3使用完备说明
    C语言经典例题-20
    【JavaScript高级】03-JavaScript内存管理和闭包
  • 原文地址:https://blog.csdn.net/qq_43417265/article/details/126070121