Rayman的绝顶之路——Leetcode每日一题打卡7

Leetcode1248. 统计「优美子数组」 题目:

给你一个整数数组 nums 和一个整数 k。

如果某个 连续 子数组中恰好有 k 个奇数数字,我们就认为这个子数组是「优美子数组」。

请返回这个数组中「优美子数组」的数目。

示例 1:

输入: nums = [1,1,2,1,1], k = 3
输出: 2
解释: 包含 3 个奇数的子数组是 [1,1,2,1] 和 [1,2,1,1] 。

示例 2:

输入: nums = [2,4,6], k = 1
输出: 0
解释: 数列中不包含任何奇数,所以不存在优美子数组。

示例 3:

输入: nums = [2,2,2,1,2,2,1,2,2,2], k = 2
输出: 16

提示:

  • 1 <= nums.length <= 50000
  • 1 <= nums[i] <= 10^5
  • 1 <= k <= nums.length

思路1(滑动窗口):

  1. 遍历给定的数组nums,找出其中所有奇数的下标,存入新的数组arr中,arr左边界为−1,右边界为arr.length;
  2. 然后遍历arr数组,寻找k个奇数,即k位;
  3. 每次搜索到k个奇数时,它的所有组合就等于下标为((最大位数+1)的值-最大位数的值)*(最小位数的值-(最小位数-1的值)),可以表达为公式:(arr[i]−arr[i−1])∗(arr[i+k]−arr[i+k−1]);
  4. 将所有的组合相加得到数组中「优美子数组」的数目。

Java AC代码:

public class Leetcode1248 {
    static int numberOfSubarrays(int[] nums, int k) {
        int len = nums.length, res = 0, feed = 0, arr[] = new int[len + 2];
        for (int i = 0; i < len; i++) {
            // 为奇数时
            if ((nums[i] & 1) == 1) {
                arr[++feed] = i;
            }
        }
        // arr左边界
        arr[0] = -1;
        // arr右边界
        arr[feed + 1] = len;
        for (int i = 1; i + k < feed + 2; i++) {
            res += (arr[i] - arr[i - 1]) * (arr[i + k] - arr[i + k - 1]);
        }
        return res;
    }

    public static void main(String[] args) {
        System.out.println(numberOfSubarrays(new int[]{2, 2, 2, 1, 2, 2, 1, 2, 2, 2}, 2));
    }
}

思路2:
做完这题去题解区看到了一个真大佬的解答,把我看得一愣一愣的,这里发出来分享给大家,希望有看懂的大佬来给我讲一讲这种方法的原理。

  1. 直接将间隔的偶数个数放入list集合即可。
  2. 比如[2,1,1,2],计算间隔就是[(2)2,1,(1)1,2(2)],即[2,1,2]。
  3. 如果k=1,那么就是21+12,如果k=2,那么就是2*2.

大佬代码如下:

public class Solution {
    public int numberOfSubarrays(int[] nums, int k) {
        int preEven = 0;
        //arrayList换成普通数组速度更快
        List<Integer> list = new ArrayList<>();
        for (int i : nums) {
            if ((i & 1) == 0) {
                preEven++;
            } else {
                list.add(preEven + 1);
                preEven = 0;
            }
        }
        list.add(preEven + 1);
        // list.forEach(o-> System.out.println(o));
        int count = 0;
        for (int i = 0; i < list.size() - k; i++) {
            count += (list.get(i) * list.get(i + k));
        }
        return count;
    }
}

看了大佬的代码瑟瑟发抖:)
2020.4.21打卡

发布了10 篇原创文章 · 获赞 0 · 访问量 158

猜你喜欢

转载自blog.csdn.net/qq_40417046/article/details/105655323