Maximum Number of Operations to Move Ones to the End

medium string greedy counting

Problem

You are given a binary string s. In one operation you pick an index i with s[i] == '1' and s[i + 1] == '0', then slide that '1' to the right until it hits the end of the string or another '1'. You may repeat this any number of times. Return the maximum number of operations you can perform.

The greedy insight: it is always best to operate on the lowest possible index first. Scanning left to right, keep a count of the '1's seen so far in the current run; every time a run of '1's is followed by a '0', each of those collected '1's contributes one operation.

Inputs = "1001101"
Output4
The two leading 1s each cross the first 0-gap (2 ops), then the three accumulated 1s cross the next 0-gap. Total 4 operations.

def maxOperations(s):
    ans = 0                       # total operations counted
    ones = 0                      # 1s collected in the current run
    for i in range(len(s)):
        if s[i] == '1':
            ones += 1             # another 1 ready to slide right
        elif i > 0 and s[i - 1] == '1':
            ans += ones           # a 1->0 boundary: each 1 moves once
    return ans
function maxOperations(s) {
  let ans = 0;                    // total operations counted
  let ones = 0;                   // 1s collected in the current run
  for (let i = 0; i < s.length; i++) {
    if (s[i] === "1") {
      ones++;                     // another 1 ready to slide right
    } else if (i > 0 && s[i - 1] === "1") {
      ans += ones;                // a 1->0 boundary: each 1 moves once
    }
  }
  return ans;
}
int maxOperations(String s) {
    int ans = 0;                  // total operations counted
    int ones = 0;                 // 1s collected in the current run
    for (int i = 0; i < s.length(); i++) {
        if (s.charAt(i) == '1') {
            ones++;               // another 1 ready to slide right
        } else if (i > 0 && s.charAt(i - 1) == '1') {
            ans += ones;          // a 1->0 boundary: each 1 moves once
        }
    }
    return ans;
}
int maxOperations(string s) {
    int ans = 0;                  // total operations counted
    int ones = 0;                 // 1s collected in the current run
    for (int i = 0; i < (int)s.size(); i++) {
        if (s[i] == '1') {
            ones++;               // another 1 ready to slide right
        } else if (i > 0 && s[i - 1] == '1') {
            ans += ones;          // a 1->0 boundary: each 1 moves once
        }
    }
    return ans;
}
Time: O(n) Space: O(1)