zoukankan      html  css  js  c++  java
  • 滑动窗口-区间统计

    2020-03-10 13:04:56

    问题描述:

    给定一个01数组 arr 和 一个整数 k, 统计有多少区间符合如下条件:

    1. 区间的两个端点都为 0 (允许区间长度为1)
    2. 区间内 1 的个数不多于 k

    样例

    样例 1:

    输入: arr = [0, 0, 1, 0, 1, 1, 0], k = 1
    输出: 7
    解释: [0, 0], [1, 1], [3, 3], [6, 6], [0, 1], [0, 3], [1, 3] (区间 [i,j] 表示下标 i(包括)和下标 j(包括)之间的元素)
    

    样例 2:

    输入: arr = [1, 1, 1, 0, 0, 1], k = 2
    输出: 3
    解释: [3, 3], [4, 4], [3, 4] (区间 [i,j] 表示下标 i(包括)和下标 j(包括)之间的元素)
    

    注意事项

    arr 的大小不超过 10^5

    问题求解:

    暴力求解O(n ^ 2),显然是会爆掉的。

    区间计数问题通常可以考虑使用滑动窗口来在O(n)的时间复杂度内完成求解。

    shrink的策略:[start, end]中1的个数 > k的时候start需要右移,并且需要移动到下一个1的位置。

    对于符合条件的[start, end]其中区间个数为end - start + 1 - cnt,可以理解为以end结尾的所有区间个数。当所有当前start对应的end都结束了之后,我们就需要移动start到下一个位置,重新开始计算。

        public long intervalStatistics(int[] nums, int k) {
            long res = 0;
            int n = nums.length;
            int start = 0;
            while (start < n && nums[start] != 0) start += 1;
            int cnt = 0;
            for (int end = start; end < n; end += 1) {
                if (nums[end] == 1) cnt += 1;
                while (cnt > k) {
                    cnt -= nums[start];
                    start += 1;
                }
                while (start < n && nums[start] != 0) {
                    cnt -= nums[start];
                    start += 1;
                }
                if (nums[end] == 0) res += end - start + 1 - cnt;
            }
            return res;
        }
    

      

  • 相关阅读:
    win10下VMware15运行ubuntu18.04无法和主机之间复制粘贴问题
    Redis的五种数据类型
    celery的入门使用
    Django/Flask的一些实现方法
    Python3实现简单的钉钉机器人调用
    装饰者模式
    pyhdfs安装
    使用setup.py安装python包和卸载python包的方法
    zookeeper搭建
    S3C6410裸奔之旅——RVDS2.2编译、仿真、调试过程 LED流水灯---转的
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/12455082.html
Copyright © 2011-2022 走看看