3499.操作后最大活跃区段数I

目标

给你一个长度为 n 的二进制字符串 s,其中:

  • '1' 表示一个 活跃 区段。
  • '0' 表示一个 非活跃 区段。

你可以执行 最多一次操作 来最大化 s 中的活跃区段数量。在一次操作中,你可以:

  • 将一个被 '0' 包围的连续 '1' 区块转换为全 '0'。
  • 然后,将一个被 '1' 包围的连续 '0' 区块转换为全 '1'。

返回在执行最优操作后,s 中的 最大 活跃区段数。

注意:处理时需要在 s 的两侧加上 '1' ,即 t = '1' + s + '1'。这些加上的 '1' 不会影响最终的计数。

示例 1:

输入: s = "01"
输出: 1
解释:
因为没有被 '0' 包围的 '1' 区块,因此无法进行有效操作。最大活跃区段数为 1。

示例 2:

输入: s = "0100"
输出: 4
解释:
字符串 "0100" → 两端加上 '1' 后得到 "101001" 。
选择 "0100","101001" → "100001" → "111111" 。
最终的字符串去掉两端的 '1' 后为 "1111" 。最大活跃区段数为 4。

示例 3:

输入: s = "1000100"
输出: 7
解释:
字符串 "1000100" → 两端加上 '1' 后得到 "110001001" 。
选择 "000100","110001001" → "110000001" → "111111111"。
最终的字符串去掉两端的 '1' 后为 "1111111"。最大活跃区段数为 7。

示例 4:

输入: s = "01010"
输出: 4
解释:
字符串 "01010" → 两端加上 '1' 后得到 "1010101"。
选择 "010","1010101" → "1000101" → "1111101"。
最终的字符串去掉两端的 '1' 后为 "11110"。最大活跃区段数为 4。

说明:

  • 1 <= n == s.length <= 10^5
  • s[i] 仅包含 '0' 或 '1'

思路

有一个二进制字符串,在其首尾拼上 1,然后执行一次操作:将一个被 0 包围的连续 1 全部转为 0,然后将一个被 1 包围的连续 0 全部转为 1,求操作之后 字符串1 的最大个数(不包括首尾拼接的 1)。

实际上是求字符串中 1 两侧连续 0 的最大长度。

判断 01 分界,记录之前连续 0 的个数与当前连续 0 的个数之和的最大值。

代码


/**
 * @date 2026-07-21 10:41
 */
public class MaxActiveSectionsAfterTrade3499 {

    public int maxActiveSectionsAfterTrade(String s) {
        int n = s.length();
        int prevZero = 0;
        int curZero = 0;
        int oneCnt = 0;
        int max = 0;
        for (int i = 0; i < n; i++) {
            if (s.charAt(i) == '1') {
                oneCnt++;
                if (curZero > 0) {
                    if (prevZero > 0) {
                        max = Math.max(max, curZero + prevZero);
                    }
                    prevZero = curZero;
                    curZero = 0;
                }
            } else {
                curZero++;
            }
        }
        if (curZero > 0) {
            if (prevZero > 0) {
                max = Math.max(max, curZero + prevZero);
            }
        }
        return oneCnt + max;
    }

}

性能