Article Categories
- All Categories
-
Data Structure
-
Networking
-
RDBMS
-
Operating System
-
Java
-
MS Excel
-
iOS
-
HTML
-
CSS
-
Android
-
Python
-
C Programming
-
C++
-
C#
-
MongoDB
-
MySQL
-
Javascript
-
PHP
-
Economics & Finance
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.
