LC2380. 二进制字符串重新安排顺序需要的时间

在这里插入图片描述

数据范围比较小,用 O ( n 2 ) O(n^2) O(n2)的暴力完全可以过,但是题目说给出一种 O ( n ) O(n) O(n)的算法。

每次交换就是把一个1向前移动了一位。当完成全部交换后,得到的字符串应该是1全部在前、0全部在后。

假设每一步每个1都能移动,那么答案应该是每个1的目标位置与当前位置的差取最大值。但是这个假设是不成立的,当出现连续两个1时,靠后的1就无法在这一步移动。

考虑每个1对它之后1的阻挡会比较复杂。但实际上,对于第i个1来说,只需要考虑它的前一个1对它的阻挡。

如果第i-1个1在k步后到达目标位置,那么第i个1至少需要k+1步才能到达目标位置:

在第k-1步时,第i-1个1到达目标之前的位置,也就是第i个1的目标位置。此时,第i个1最多只能到达目标的前一位。而在第k步时,第i-1个1到达目标,但第i个1由于被阻挡或步数不够所以不能到达目标位置。因此至少需要k+1步才能到达目标。

此外,一旦两个1之间相隔不超过一个0,那么在此之后它们之间至多只会相隔一个0。如果前一个1被阻挡,那么后一个1会追上它;如果两个连续的1中前一个1可以移动,那么后一个1会在下一步开始移动。因此,如果两个1在移动过程中出现了这样的情况,那么它们所需的步数一定满足上述的关系。而如果没有出现这样的情况,说明前一个1始终没有阻挡当前的1,它移动到目标的步数就是与目标位置的距离。答案在两者之间取较大值即可。

此外需要注意的是,对于一开始就在目标位置的1来说,它们所需的步数是0,不按照上述规则计算。

class Solution {
    
    
public:
    int secondsToRemoveOccurrences(string s) {
    
    
        int sz=s.size();
        int pre=0;
        int ans=0;
        for(int i=0;i<sz;++i)
        {
    
    
            if(s[i]=='0')
            {
    
    
                ++pre;
                continue;
            }
            if(pre==0)
                ans=0;
            else
                ans=max(ans+1,pre);
        }
        return ans;
    }
};

猜你喜欢

转载自blog.csdn.net/m0_49792815/article/details/129417552
今日推荐