【数组】B067_LC_和为K的子数组(暴力 / 前缀和 + map)

一、Problem

Given an array of integers and an integer k, you need to find the total number of continuous subarrays whose sum equals to k.

Input:nums = [1,1,1], k = 2
Output: 2

The length of the array is in range [1, 20,000].
The range of numbers in the array is [-1000, 1000] and the range of the integer k is [-1e7, 1e7].

二、Solution

方法一:暴力

…不多说,简单一次过…,运算量大概 10810^8,可以过。

class Solution {
    public int subarraySum(int[] nums, int k) {
        int n = nums.length, cnt = 0;
        for (int l = 0; l < n; l++) {
            int sum = nums[l];
            if (sum == k)
                cnt++;
            for (int r = l + 1; r < n; r++) {
                sum += nums[r];
                if (sum == k)
                    cnt++;
            }
        }
        return cnt;
    }
}

复杂度分析

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

方法二:哈希

过了就没多想了,这是别人的前缀和 + map,仅供参考:由前缀和公式得,如果下式满足,符合条件的子数组加 1
pre[i]pre[j]=kpre[i] - pre[j] = k
又通过移项得以下公式,
pre[j]=pre[i]kpre[j] = pre[i] - k
这似乎告诉我们:当当前的前缀和为 pre[i]pre[i] 时,我们只要找到和为 pre[i]kpre[i] - k 数值的个数即为和为 kk 的子数组的个数。

class Solution {
    public int subarraySum(int[] nums, int k) {
        int cnt = 0, pre = 0;
        Map<Integer, Integer> mp = new HashMap<>();
        mp.put(0, 1);
        for (int n : nums) {
            pre += n;
            int tar = pre - k;
            if (mp.containsKey(tar))
                cnt += mp.get(tar);
            mp.put(pre, mp.getOrDefault(pre, 0)+1);
        }
        return cnt;
    }
}

复杂度分析

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

相关:

  • 连续的子数组和
    乘积小于K的子数组
    和可被 K 整除的子数组
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章