• 【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)

  • 相关阅读:
    Linux驱动开发 --- 模块加载和ELF文件
    How to install nodejs.16 to Linux mint 21.0
    .so文件【Linux下的程序函数库,即编译好的可以供其他程序使用的代码和数据】
    SWT/ANR问题--SWT 导致 low memory killer(LMK)
    自定义JPA函数扩展,在specification中实现位运算
    简易实现通讯录3.0 (实现文件操作)
    云原生—Rust编程语言能与CC++媲美
    支付宝H5支付
    Windbg常用命令详解
    OpenVINO相关
  • 原文地址:https://blog.csdn.net/qq_43417265/article/details/126070121