【數組】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 整除的子數組
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章