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;
        }
    

      

  • 相关阅读:
    FastDFS介绍
    SwiftUI 中使用SDWebImageSwiftUI加载网络图片
    SwiftUI 中使用BBSwiftUIKit开源库实现上拉加载和下拉刷新
    SwiftUI 中使用ScrollView+LazyVStack代替List
    SwiftUI 动画
    SwiftUI 中实现省市区选择器
    SwiftUI 中Slider的使用
    SwiftUI 中Stepper的使用
    SwiftUI 中通过Toggle实现单选框和复选框效果
    SwiftUI 中加载bundle中的图片
  • 原文地址:https://www.cnblogs.com/hyserendipity/p/12455082.html
Copyright © 2011-2022 走看看