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

文章讨论了一个关于二进制字符串的问题,其中给定一个二进制字符串和一个整数数组,表示按步骤翻转字符串的位。目标是计算在翻转过程中字符串达到前缀一致状态的次数。文章提出了暴力解法的时间复杂度问题,并给出了使用最大位置索引和线性时间复杂度的解决方案。此外,还提到了树状数组作为优化验证过程的可能性。
摘要由CSDN通过智能技术生成

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)$的时间内完成验证。

或者也可以使用树状数组,每次操作更新树状数组的1个位置为1,然后验证1~cnt的前缀和 p r e s u m = = c n t presum==cnt presum==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

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Eric.Cui

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值