Quick Overview

Given a string of lowercase letters, find the minimum number of single-position replacements needed so that no two adjacent characters are equal. It tests turning an adjacency constraint into an exact minimum count, justifying why fewer operations cannot work, and handling edge cases in an efficient solution.

Minimum Character Replacements So No Two Adjacent Characters Are Equal

Company: Headlands

Role: Data Scientist

Category: Coding & Algorithms

Difficulty: medium

Interview Round: Online Assessment

Given a string `s` of lowercase English letters, one operation replaces the character at any single position with any lowercase English letter. Return the minimum number of operations needed so that no two adjacent characters in the resulting string are equal. ### Function Signature ```python def min_replacements(s: str) -> int: ``` ### Rules - Each operation changes exactly one position. The replacement may be any lowercase letter, including one that already appears elsewhere in `s`. - Only replacements are allowed; characters cannot be inserted, deleted, or reordered. - The resulting string is valid when `s[i] != s[i + 1]` for every `0 <= i < len(s) - 1`. A string of length 1 is always valid. - Return a single integer: the minimum number of operations. Several different resulting strings may achieve that minimum, but the count itself is unique, so only the count is returned. A string that is already valid returns `0`. ### Constraints - `1 <= len(s) <= 100000` - Every character of `s` is a lowercase English letter from `a` to `z`. ### Examples Input: `s = "aab"` Output: `1` Replacing the character at index 1 with `c` gives `"acb"`. Input: `s = "aaaa"` Output: `2` Two replacements suffice, for example giving `"abab"`. Input: `s = "abcabc"` Output: `0`

Overview: Given a string of lowercase letters, find the minimum number of single-position replacements needed so that no two adjacent characters are equal. It tests turning an adjacency constraint into an exact minimum count, justifying why fewer operations cannot work, and handling edge cases in an efficient solution.

Read the full Headlands Data Scientist interview experience this question came from

You are given a string `s` of lowercase English letters. In one operation you may replace the character at any single position with any lowercase English letter (the replacement may be a letter that already appears elsewhere in `s`). Characters cannot be inserted, deleted, or reordered. Return the minimum number of operations needed so that the resulting string has no two adjacent equal characters, i.e. `s[i] != s[i + 1]` for every `0 <= i < len(s) - 1`. A string of length 1 is always valid, and a string that is already valid returns `0`. Several different resulting strings may achieve the minimum, but the count itself is unique, so only the count is returned (a single integer). Example 1: Input: s = "aab" Output: 1 Explanation: Replacing the character at index 1 with 'c' gives "acb". Example 2: Input: s = "aaaa" Output: 2 Explanation: Two replacements suffice, for example giving "abab". Example 3: Input: s = "abcabc" Output: 0 Constraints: - 1 <= len(s) <= 100000 - Every character of s is a lowercase English letter from 'a' to 'z'. The answer is at most len(s) / 2 = 50000, so it always fits in a 32-bit signed integer.

Constraints

  • 1 <= len(s) <= 100000
  • Every character of s is a lowercase English letter from 'a' to 'z'.

Examples

Input: ('a',)

Expected Output: 0

Explanation: A single character is always valid.

Input: ('zz',)

Expected Output: 1

Explanation: Two equal letters at the alphabet edge need one change.

Hints

  1. Think about which parts of the string actually need to change: look at stretches of consecutive identical characters.
  2. Can a change inside one stretch of identical characters ever affect a different stretch?
  3. For a single stretch of identical characters of length L, find a lower bound on the changes needed and check whether it can be achieved.

Loading coding console...

Show the approach

Approach

Split s into maximal runs of equal characters. Runs are independent: adjacent runs already differ at their boundary. A run of length L contains floor(L/2) disjoint equal adjacent pairs (positions (0,1), (2,3), ...), and each pair needs at least one of its two positions changed, so at least floor(L/2) operations are required for that run. That many is also enough: change the characters at run offsets 1, 3, 5, ... (floor(L/2) positions) to a letter that differs from both of its neighbors, which always exists because there are 26 letters and at most 2 neighbors. No changed position is adjacent to another changed position, and unchanged positions within a run are never adjacent to each other, so the result is valid. The answer is therefore the sum of floor(L/2) over all runs. The implementation scans once, extending the current run while characters repeat and flushing floor(run/2) whenever the character changes and once more at the end (forgetting the final flush is the classic bug for runs at the end of the string). A length-1 string is a single run of length 1 and yields 0.

Time complexity:
O(n)
Space complexity:
O(1)