Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1758. Minimum Changes To Make Alternating Binary String - Leetcode Solution

Problem Description

Given a binary string s (i.e., a string consisting only of the characters '0' and '1'), your task is to determine the minimum number of character changes required to make s alternate between '0' and '1'. An alternating binary string is one where no two adjacent characters are the same. For example, "0101" and "1010" are alternating, but "0011" and "110" are not.

  • You can change any character in s to either '0' or '1'.
  • Return the minimum number of changes needed to make s alternating.

Constraints:

  • 1 <= s.length <= 10^4
  • s consists only of '0' and '1'.

Thought Process

The problem asks for the minimum number of changes to turn a binary string into an alternating one. At first glance, you might consider checking every possible way to alternate the string by flipping characters one by one, but that would be inefficient.

Instead, notice that an alternating string can only be of two forms:

  • Starts with '0', i.e., "010101..."
  • Starts with '1', i.e., "101010..."
For each position in the string, we can check what the expected character should be for both patterns. By comparing the current character to each pattern, we can count how many changes are needed for both possibilities. The answer will be the minimum of these two counts.

Solution Approach

We want to efficiently determine the minimum number of changes required. Here’s how we approach it:

  1. Identify the two possible alternating patterns:
    • Pattern A: Starts with '0' (i.e., positions 0,2,4... should be '0'; positions 1,3,5... should be '1')
    • Pattern B: Starts with '1' (i.e., positions 0,2,4... should be '1'; positions 1,3,5... should be '0')
  2. Iterate through the string:
    • For each character at index i, determine what it should be for both patterns.
    • If the actual character differs from the pattern, increment the change count for that pattern.
  3. Return the minimum:
    • After processing the entire string, return the smaller of the two counts.

This approach is efficient because it only requires a single pass through the string and constant extra space.

Example Walkthrough

Let's walk through the example s = "0100":

  • Pattern A (starts with '0'):
    • Index 0: Should be '0' (matches, no change)
    • Index 1: Should be '1' (matches, no change)
    • Index 2: Should be '0' (matches, no change)
    • Index 3: Should be '1' (actual is '0', needs change)

    Changes needed: 1

  • Pattern B (starts with '1'):
    • Index 0: Should be '1' (actual is '0', needs change)
    • Index 1: Should be '0' (actual is '1', needs change)
    • Index 2: Should be '1' (actual is '0', needs change)
    • Index 3: Should be '0' (matches, no change)

    Changes needed: 3

The minimum number of changes required is 1.

Code Implementation

class Solution:
    def minOperations(self, s: str) -> int:
        changes_start_0 = 0
        changes_start_1 = 0
        for i, c in enumerate(s):
            expected_0 = '0' if i % 2 == 0 else '1'
            expected_1 = '1' if i % 2 == 0 else '0'
            if c != expected_0:
                changes_start_0 += 1
            if c != expected_1:
                changes_start_1 += 1
        return min(changes_start_0, changes_start_1)
      
class Solution {
public:
    int minOperations(string s) {
        int changes_start_0 = 0, changes_start_1 = 0;
        for (int i = 0; i < s.size(); ++i) {
            char expected_0 = (i % 2 == 0) ? '0' : '1';
            char expected_1 = (i % 2 == 0) ? '1' : '0';
            if (s[i] != expected_0) ++changes_start_0;
            if (s[i] != expected_1) ++changes_start_1;
        }
        return min(changes_start_0, changes_start_1);
    }
};
      
class Solution {
    public int minOperations(String s) {
        int changesStart0 = 0, changesStart1 = 0;
        for (int i = 0; i < s.length(); i++) {
            char expected0 = (i % 2 == 0) ? '0' : '1';
            char expected1 = (i % 2 == 0) ? '1' : '0';
            if (s.charAt(i) != expected0) changesStart0++;
            if (s.charAt(i) != expected1) changesStart1++;
        }
        return Math.min(changesStart0, changesStart1);
    }
}
      
var minOperations = function(s) {
    let changesStart0 = 0, changesStart1 = 0;
    for (let i = 0; i < s.length; i++) {
        let expected0 = i % 2 === 0 ? '0' : '1';
        let expected1 = i % 2 === 0 ? '1' : '0';
        if (s[i] !== expected0) changesStart0++;
        if (s[i] !== expected1) changesStart1++;
    }
    return Math.min(changesStart0, changesStart1);
};
      

Time and Space Complexity

Brute-force approach: If you tried all possible combinations or performed swaps, you might have exponential time complexity, which is impractical for large strings.

Optimized approach: The solution above performs a single pass through the string, comparing each character to the two possible alternating patterns.

  • Time Complexity: O(n), where n is the length of the string s, because we check each character once.
  • Space Complexity: O(1), because we only use a few integer counters, regardless of the input size.
This makes the solution highly efficient even for the largest allowed inputs.

Summary

To solve the Minimum Changes To Make Alternating Binary String problem, we recognize that only two alternating patterns are possible. By counting the mismatches for both patterns in a single pass, we efficiently determine the minimum number of changes needed. This approach is simple, elegant, and optimal, making it a great example of reducing a problem to its fundamental patterns and leveraging symmetry for efficiency.