Program to form smallest number where no two adjacent digits are same in Python

Suppose we have a string s with four possible characters "1", "2", "3" and "?". We can place any one of "1", "2" and "3" in the place of "?". We have to find the smallest possible number that we can make such that no two adjacent digits are same.

So, if the input is like s = "2??3?", then the output will be 21231.

Algorithm

To solve this, we will follow these steps ?

  • Convert the string to a list for easy modification
  • Handle the special case where string length is less than 2
  • Iterate through each position and replace "?" with the smallest digit (1, 2, or 3) that doesn't match adjacent digits
  • For the first position, only check the next digit
  • For middle positions, check both previous and next digits
  • For the last position, only check the previous digit

Example

Let us see the following implementation to get better understanding ?

def solve(s):
    s = list(s)
    
    # Handle single character case
    if len(s) < 2:
        if s[0] == "?":
            return "1"
        return "".join(s)
    
    for i in range(len(s)):
        if s[i] == "?":
            # Try digits 1, 2, 3 and pick the first valid one
            for digit in ["1", "2", "3"]:
                valid = True
                
                # Check left neighbor
                if i > 0 and s[i-1] == digit:
                    valid = False
                
                # Check right neighbor
                if i < len(s) - 1 and s[i+1] == digit:
                    valid = False
                
                if valid:
                    s[i] = digit
                    break
    
    return "".join(s)

# Test with example
s = "2??3?"
result = solve(s)
print(f"Input: {s}")
print(f"Output: {result}")
Input: 2??3?
Output: 21231

Step-by-Step Execution

Let's trace through the example "2??3?" ?

def solve_with_trace(s):
    print(f"Original string: {s}")
    s = list(s)
    
    for i in range(len(s)):
        if s[i] == "?":
            print(f"\nProcessing position {i}: {''.join(s)}")
            
            for digit in ["1", "2", "3"]:
                valid = True
                
                # Check left neighbor
                if i > 0 and s[i-1] == digit:
                    print(f"  Digit '{digit}' conflicts with left neighbor '{s[i-1]}'")
                    valid = False
                
                # Check right neighbor  
                if i < len(s) - 1 and s[i+1] == digit:
                    print(f"  Digit '{digit}' conflicts with right neighbor '{s[i+1]}'")
                    valid = False
                
                if valid:
                    s[i] = digit
                    print(f"  Assigned '{digit}' at position {i}: {''.join(s)}")
                    break
    
    return "".join(s)

# Trace execution
result = solve_with_trace("2??3?")
print(f"\nFinal result: {result}")
Original string: 2??3?

Processing position 1: 2??3?
  Digit '1' conflicts with right neighbor '?'
  Assigned '1' at position 1: 21?3?

Processing position 2: 21?3?
  Digit '1' conflicts with left neighbor '1'
  Assigned '2' at position 2: 2123?

Processing position 4: 2123?
  Digit '1' is valid
  Assigned '1' at position 4: 21231

Final result: 21231

Key Points

  • We always try digits in order: "1", "2", "3" to get the smallest possible number
  • A digit is valid if it doesn't match any adjacent non-"?" character
  • The algorithm processes characters left to right, ensuring previous positions are already resolved
  • Time complexity is O(n) where n is the length of the string

Conclusion

This algorithm efficiently replaces each "?" with the smallest valid digit by checking adjacent characters. The greedy approach ensures we get the lexicographically smallest result while satisfying the constraint that no two adjacent digits are the same.

Updated on: 2026-03-26T16:37:05+05:30

449 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements