和相同的二元子数组

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/binary-subarrays-with-sum

题目描述:

给你一个二元数组 nums ,和一个整数 goal ,请你统计并返回有多少个和为 goal 的 非空 子数组。
子数组 是数组的一段连续部分。

示例 1:

输入:nums = [1,0,1,0,1], goal = 2
输出:4
解释:
如下面黑体所示,有 4 个满足题目要求的子数组:
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,1,0,1]
[1,0,1,0,1]

示例 2:

输入:nums = [0,0,0,0,0], goal = 0
输出:15

思路一:

暴力解法

对数组按照顺序进行累加,等于goal则count++,大于goal则开始下一轮累加,直到遍历完所有子数组.

代码实现:
class Solution {
    public int numSubarraysWithSum(int[] nums, int goal) {
        int count = 0;
        int len = nums.length;
        for (int i = 0; i < len; i++) {
            int sum = 0;
            for (int j = i; j < len; j++) {
                sum += nums[j]; 
                if (sum > goal) {
                    break;
                } else if (sum == goal) {
                    count++;
                } 
                     
            }
        }
        return count;
    }
}
思路二:

题目要求统计和为 goal 的非空子数组个数,假设存在这样的子数组nums[m]到nums[n]的和为goal,那么必然有nums[0]到nums[m]加上goal的和等于nums[0]到nums[n]的和;,因此该问题可以转换为两数和的形式。也就是sum[n](数组索引0到n的和) - goal = sum[m](数组索引0到n到和);生成一个前n项和数组sum,问题就变成了求sum中是否存在元素sum[n] = sum[m] + goal;然后使用求两数之和的方式,sum[n] - goal判断另一个元素在数组中是否存在,因为sum[n] == goal也算成立,所以需要初始化map.put(0, 1),并且对于新数组sum可能出现重复元素,例如[3,5,5,5,5],sum[1] - goal = sum[2] - goal,count都需要++,因此map需要记录重复的次数(类似大餐计数这道题)。


930. 和相同的二元子数组.png
代码实现:
class Solution {
    public int numSubarraysWithSum(int[] nums, int goal) {
        int count = 0;
        int len = nums.length;
        int[] arr = new int[len];
        int sum = 0;
        for (int i = 0; i < len; i++) {
            sum += nums[I];
            arr[i] = sum;
        }
        Map map = new HashMap();
        map.put(0,1);
        for (int i = 0; i < len; i++) {
           if (map.containsKey(arr[i] - goal)) {
               int index = map.get(arr[i] - goal);
               count += index;
           }
           Integer value = map.get(arr[I]);
           map.put(arr[i], value == null ? 1 : ++value);
        }
        return count;
    }
}

你可能感兴趣的:(和相同的二元子数组)