帖子
- 魔法师2026-07-2113093
力扣 LeetCode

3499. 操作后最大活跃区段数 I - 力扣(LeetCode)
3499. 操作后最大活跃区段数 I - 给你一个长度为 n 的二进制字符串 s,其中:
- '1' 表示一个 活跃 区段。
- '0' 表示一个 非活跃 区段。
你可以执行 最多一次操作 来最大化 s 中的活跃区段数量。在一次操作中,你可以:
- 将一个被 '0' 包围的连续 '1' 区块转换为全 '0'。
- 然后,将一个被 '1' 包围的连续 '0' 区块转换为全 '1'。
返回在执行最优操作后,s 中的 最大 活跃区段数。
注意:处理时需要在 s 的两侧加上 '1'...
思路
统计两段相邻的非活跃(连续0)区段,转为活跃区段即可。如果不足两段记为0。
本来挺简单一题。。我一开始脑补了 连续 二字,给做麻烦了,而且给出的示例测起来也没问题!!!(甚至提交的时候过了105个用例)
错误代码如下```
class Solution {
public int maxActiveSectionsAfterTrade(String s) {
char last = '1';
int cnt1l = 0, cnt0l = 0, cnt1m = 0, cnt0r = 0, cnt1r = 0;
int cnt = 0;
int ans = 0;
int n = s.length();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
if (c == last) {
cnt++;
continue;
}
if (c == '1') {
if (cnt0l == 0) {
cnt0l = cnt;
} else {
cnt0r = cnt0l;
cnt0l = cnt;
}
} else {
if (cnt1l == 0) {
cnt1l = cnt;
} else if (cnt1m == 0) {
cnt1m = cnt1l;
cnt1l = cnt;
} else {
cnt1r = cnt1m;
cnt1m = cnt1l;
cnt1l = cnt;
ans = Math.max(ans, cnt1l + cnt0l + cnt1m + cnt0r + cnt1r);
}
}
cnt = 1;
last = c;
}
if (last == '1') {
if (cnt1l == 0) {
ans = cnt;
} else if (cnt1m == 0) {
ans = Math.max(cnt1l, cnt);
} else {
ans = Math.max(ans, cnt1l + cnt0l + cnt1m + cnt0r + cnt);
}
} else {
if (cnt0l == 0) {
ans = cnt1l;
} else {
ans = Math.max(ans, cnt1l + cnt0l + cnt1m + cnt);
}
}
return ans;
}
}
``代码``
class Solution {
public int maxActiveSectionsAfterTrade(String s) {
char last = '1';
int cnt0l = 0, cnt0r = 0, cnt1 = 0;
int cnt = 0, max = 0;
int n = s.length();
for (int i = 0; i < n; i++) {
char c = s.charAt(i);
if (c == '1') {
cnt1++;
}
if (c == last) {
cnt++;
continue;
}
if (c == '1') {
if (cnt0l != 0) {
cnt0r = cnt0l;
cnt0l = cnt;
max = Math.max(max, cnt0r + cnt0l);
} else {
cnt0l = cnt;
}
}
cnt = 1;
last = c;
}
if (last == '0') {
if (cnt0l != 0) {
max = Math.max(max, cnt + cnt0l);
}
}
return cnt1 + max;
}
}主楼 - SomeBottle2026-07-2111179
题意有点绕,读了半天才懂。
题目中的操作只能执行一次,这一次操作分两步。因为两端有虚拟的 1,第二步必然能操作,因此能不能把 0…1…0 转换为 0…0…0 再转换为 1…1…1,主要就看能不能找到符合第一步要求的 0…1…0 形式。
然后要求结果找到最大的 1 数量,因此我们要找到 0…1…0 形式中全变成 1,转换最多的 0 的数目。
注意最终结果要的是转换后总的 1 数量。```
class Solution {
public:
int maxActiveSectionsAfterTrade(string s) {
// 意思是两端都有虚拟的 1
// 操作只能执行一次,一次操作分两步,先看被 0 包围的,转换后再看被 1 包围的
// 因为两端有虚拟的 1,第二步必然是有的int oneCnt=0; // 对原本 s 中的 1 数量进行计数
int prevZeros=0;
int prevOnes=0;
int currZeros=0;
int currOnes=0;
int transformed=0; // 被转换为 1 的最大 0 数量
if(s[0]=='0'){
currZeros++;
}else{
oneCnt++;
}
for(int i=1;i<s.size();i++){
if(s[i]!=s[i-1]){
// 出现交界
if(s[i]=='0'){
// 前面一段是 1
prevOnes=currOnes;
currOnes=0;
}else{
if(prevZeros>0){
// 前面一段是 0 且形成了 0 - 1 - 0 的情况
// 包围 1 的 0 都可转换为 1
// 结算
transformed=max(transformed,prevZeros+currZeros);
}
prevZeros=currZeros;
currZeros=0;
prevOnes=0;
}
}
if(s[i]=='0'){
currZeros++;
if(i==s.size()-1&&prevZeros>0){
// 最后一个位置是 0,也要结算一下
transformed=max(transformed, prevZeros+currZeros);
}
}else{
currOnes++;
oneCnt++;
}
}
return oneCnt+transformed;
}
}; - Infinity4B2026-07-2121802
原题评论区说的好

算术评级4 第 153 场双周赛 Q2 难度分1729```
class Solution:
def maxActiveSectionsAfterTrade(self, s: str) -> int:
s = '1' + s + '1'
prev_zero, cur_zero, cur_one = None, 0, 0
max_added = 0
n = len(s)
for i in range(n):
if s[i]=='0':
cur_zero+=1
cur_one = 0
elif i==0 or s[i-1]=='1':
cur_one+=1
else:
if prev_zero is not None:
max_added = max(max_added, prev_zero+cur_zero)
prev_zero = cur_zero
cur_zero = 0
return s.count('1')-2+max_added - snow2026-07-2134832
class Solution { public: int maxActiveSectionsAfterTrade(string s) { int mx = 0, ans = 0; int lst0 = 0; int i = 0, j = 0; int n = s.size(); while (i < n) { int j = i; while (j < n and s[j] == s[i]) { j++; } if (s[i] == '1') { ans += j - i; } else { if (lst0 != 0) { mx = max(mx, j - i + lst0); } lst0 = j - i; } i = j; } return ans + mx; } }; - CPython2026-07-2114995
逆天的题目 真读不懂
Codex 帮我理解的```
class Solution:
def maxActiveSectionsAfterTrade(self, s: str) -> int:
tt = s.count('1')
l = pre = cur = 0
ans = 0
n = len(s)
while l < n:
if s[l] == '1':
l += 1
continue
r = l
while r < n and s[r] == '0':
r += 1
cur = r - l
if pre:
ans = max(ans, pre + cur)
pre = cur
l = r
return ans + tt