#3499
Medium Algorithms Maximize active section with trade i
String Enumeration
31.2% acceptance
Feb 25, 2026
69
28
You are given a binary string s of length n, where:
'1' represents an active section.
'0' represents an inactive section.
You can perform at most one trade to maximize the number of active sections in s. In a trade, you:
Convert a contiguous block of '1's that is surrounded by '0's to all '0's.
Afterward, convert a contiguous block of '0's that is surrounded by '1's to all '1's.
Return the maximum number of active sections in s after making the optimal trade.
Note: Treat s as if it is augmented with a '1' at both ends, forming t = '1' + s + '1'. The augmented '1's do not contribute to the final count.
Solution
Rust
Time O(n²)
Space O(n)
impl Solution {
pub fn max_active_sections_after_trade(s: String) -> i32 {
let _n = s.len();
let b = s.as_bytes();
// Count initial active sections
let base = b.iter().filter(|&&c| c == b'1').count() as i32;
// Trade: find a block of 1s surrounded by 0s (or augmented 1s), convert to 0s.
// Then find a block of 0s surrounded by 1s (or augmented), convert to 1s.
// Treat t = "1" + s + "1". Find zero-blocks and one-blocks in t.
// A zero-block in t at position [i..j] is surrounded by 1s (since t has 1s at ends and valid structure).
// A one-block in t (not counting the augmented ends) is [i..j] surrounded by 0s.
// Trade: pick a one-block B1 surrounded by zeros, convert to zeros.
// Then the surrounding zeros might form a larger zero-block.
// Actually: after converting B1 to zeros, we get a larger zero-block. Then convert that to ones.
// Net gain: (size of new zero-block) - (original zero-block size we used).
// The blocks in t = "1"+s+"1":
// Alternating zero-blocks and one-blocks.
// Segments of 0s in t are the places we can convert.
// Strategy:
// 1. Find all zero-runs Z1, Z2, ... in t (adjacent ones separate them).
// 2. Each one-run O1, O2, ... (in t, ignoring augmented ends) between consecutive zero-runs.
// 3. If we convert O_k (surrounded by Z_k and Z_{k+1}) to zeros, we merge Z_k, O_k, Z_{k+1}.
// New zero-run size = len(Z_k) + len(O_k) + len(Z_{k+1}).
// Then we convert this new zero-run to ones.
// Net gain = len(new zero-run) - len(O_k) = len(Z_k) + len(Z_{k+1}).
// (We gain Z_k + Z_{k+1} new ones, but lose 0 active sections since O_k was already active.)
// Wait: O_k was active (all 1s). Converting to 0s: lose len(O_k). Then converting new zero-run to 1s: gain len(Z_k)+len(O_k)+len(Z_{k+1}). Net = len(Z_k)+len(Z_{k+1}).
// But augmented ends' O-blocks can't be traded (they're not "in" s).
// Build segments in t = "1" + s + "1"
let t: Vec<u8> = std::iter::once(b'1').chain(b.iter().copied()).chain(std::iter::once(b'1')).collect();
let tn = t.len();
// Find alternating blocks
let _zero_runs: Vec<usize> = vec![];
let _one_runs: Vec<usize> = vec![]; // only interior one-runs (not augmented)
// Track: t starts with 1, so first block is 1-block (augmented).
let mut i = 0;
let _in_augmented_start = true;
let mut segments: Vec<(u8, usize)> = vec![];
while i < tn {
let c = t[i];
let mut j = i;
while j < tn && t[j] == c { j += 1; }
segments.push((c, j - i));
i = j;
}
// segments[0] = ('1', ...) augmented start.
// segments[last] contains augmented end '1'.
let max_gain = if segments.len() < 3 {
0
} else {
// For each interior one-run (segments[1], segments[3], ...):
// Gain = adjacent zero-runs' lengths.
let mut best = 0i32;
for idx in (2..segments.len()-1).step_by(2) {
// segments[idx] should be a '1' run (interior)
if segments[idx].0 != b'1' { continue; }
// Adjacent zero-runs: segments[idx-1] and segments[idx+1]
if idx == 0 || idx + 1 >= segments.len() { continue; }
if segments[idx-1].0 != b'0' || segments[idx+1].0 != b'0' { continue; }
let gain = (segments[idx-1].1 + segments[idx+1].1) as i32;
if gain > best { best = gain; }
}
best
};
base + max_gain
}
}