题目
思路
- 思路一:暴力枚举,通过双重循环来计算不同起点i的前缀和(指为奇数的个数和),从而计算最终结果。
思路二:前缀和+HashMap,由于暴力枚举要计算不同起点的前缀和,但是和可以使用HashMap来优化计算过程,pre[i] - pre[j] = k表示以i结尾的前缀和减去以j结尾的前缀和的值等于k,将问题转换为pre[i] - k = pre[j],相当于求pre[j]的值,其中j < i,也就是求比i小的前缀和中有多少个值等于pre[i]-k,这是就可以使用map简化计算
代码
//1.暴力枚举public int numberOfSubarrays(int[] nums, int k) {int res = 0;for (int i = 0; i < nums.length; i++) {int count = 0;for (int j = i; j < nums.length; j++) {count += nums[j] & 1;if (count == k) res++;}}return res;}//2.前缀和 + HashMap优化计算public int numberOfSubarrays(int[] nums, int k) {int res = 0, count = 0;Map<Integer, Integer> map = new HashMap<>();map.put(0, 1);for (int num : nums) {count += (num & 1);res += map.getOrDefault(count - k, 0);map.put(count, map.getOrDefault(count, 0) + 1);}return res;}//3.前缀和 + 数组优化计算public int numberOfSubarrays(int[] nums, int k) {int res = 0, count = 0;int[] pre = new int[nums.length + 1];pre[0] = 1;for (int num : nums) {count += (num & 1);res += count >= k ? pre[count - k] : 0;pre[count]++;}return res;}
