【算法】Number of Times Binary String Is Prefix-Aligned 二进制字符串前缀一致的次数

文章目录

  • Number of Times Binary String Is Prefix-Aligned 二进制字符串前缀一致的次数
    • 问题描述:
    • 分析
    • 代码

Number of Times Binary String Is Prefix-Aligned 二进制字符串前缀一致的次数

问题描述:

给你一个长度为 n 、下标从 1 开始的二进制字符串,所有位最开始都是 0 。我们会按步翻转该二进制字符串的所有位(即,将 0 变为 1)。

给你一个下标从 1 开始的整数数组 flips ,其中 flips[i] 表示对应下标 i 的位将会在第 i 步翻转。

二进制字符串 前缀一致 需满足:在第 i 步之后,在 闭 区间 [1, i] 内的所有位都是 1 ,而其他位都是 0 。

返回二进制字符串在翻转过程中 【前缀一致】 的次数。

flips.length,n范围[1,50000]

分析

这个问题的模型已经有很多的变形,很早之前有个类似的开关灯的。
回到问题,数组的元素 a[i] 表示 在第i步时,将位置a[i]的元素置1,因为该问题中的下标是1开始的,所以需要做偏移。也就是对0开始的下标 a [ i ] − 1 a[i]-1 a[i]1进行操作。
而且要求前缀一致,也就是整个字符串会出现前半段连续1,后半段连续0.
暴力的角度就是,在每一次的操作 a [ i ] − 1 a[i]-1 a[i]1下标的元素后,检查字符串是否前缀一致。暴力的检查方式就是双指针,一个从左向右找连续1,一个从右向左找连续0,如果2指针可以相遇,即 L + 1 = = R L+1==R L+1==R,说明符合一致。思路没问题,就是整体的时间复杂度是 O ( n 2 ) O(n^2) O(n2)
但是n的规模比较大的情况下,这个时间就无法承受。
如果可以在 O ( log ⁡ 2 N ) O(\log_{2}{N}) O(log2N)或者 O ( 1 ) O(1) O(1)的时间复杂度下,完成验证,也可以提升速度。
验证的目标是找到连续的1,而且每次只会操作1个位置,如果记录下最远的1的位置,并且与当前操作的次数比较,就可以在 O ( 1 ) O(1) O(1)的时间内完成验证。

或者也可以使用树状数组,每次操作更新树状数组的1个位置为1,然后验证1~cnt的前缀和==cnt。维护树状数组的时间复杂度为对数级

代码

public int numTimesAllBlue(int[] flips) {
        int ans = 0,n = flips.length,idx =0;
        for(int i = 0;i<n;i++){
            idx = Math.max(idx,flips[i]);
            if(i+1==idx) ans++;            
        }
        return ans;
    }

时间复杂度 O ( N ) O(N) O(N)

空间复杂度: O ( 1 ) O(1) O(1)

Tag

Array

你可能感兴趣的:(数据结构与算法,算法,数据结构)