Program to find lexicographically smallest non-palindromic string in Python

Given a palindromic string, we need to change exactly one character to make it the lexicographically smallest non-palindromic string possible.

The strategy is to iterate through the first half of the string and replace the first non-'a' character with 'a'. If all characters in the first half are 'a', we change the last character to 'b'.

Example

Let's see how this works with the string "level" ?

def find_smallest_non_palindrome(s):
    # Check first half for non-'a' characters
    for i in range(len(s) // 2):
        if s[i] != "a":
            # Convert to list, change character, and return
            chars = list(s)
            chars[i] = "a"
            return "".join(chars)
    
    # If all first-half characters are 'a', change last character
    chars = list(s)
    chars[-1] = "b"
    return "".join(chars)

# Test with example
s = "level"
result = find_smallest_non_palindrome(s)
print(f"Input: {s}")
print(f"Output: {result}")
Input: level
Output: aevel

How It Works

The algorithm follows these steps:

  1. Iterate through first half: Check characters from index 0 to len(s)//2
  2. Find first non-'a': When we find a character that isn't 'a', replace it with 'a'
  3. Handle all 'a' case: If the first half contains only 'a' characters, change the last character to 'b'

Additional Examples

def find_smallest_non_palindrome(s):
    for i in range(len(s) // 2):
        if s[i] != "a":
            chars = list(s)
            chars[i] = "a"
            return "".join(chars)
    
    chars = list(s)
    chars[-1] = "b"
    return "".join(chars)

# Test multiple cases
test_cases = ["level", "abcba", "aaaa", "racecar"]

for test in test_cases:
    result = find_smallest_non_palindrome(test)
    print(f"{test} ? {result}")
level ? aevel
abcba ? aacba
aaaa ? aaab
racecar ? aacecar

Why This Works

This approach ensures lexicographical minimality because:

  • Leftmost change: We change the leftmost possible character for maximum impact
  • Smallest replacement: 'a' is the smallest letter, making the result lexicographically smallest
  • Edge case handling: When all first-half characters are 'a', changing the last character to 'b' creates the smallest possible non-palindrome

Conclusion

The algorithm efficiently finds the lexicographically smallest non-palindromic string by replacing the first non-'a' character in the first half with 'a', or the last character with 'b' if needed. This approach guarantees the optimal solution in O(n) time complexity.

Updated on: 2026-03-25T12:32:32+05:30

421 Views

Kickstart Your Career

Get certified by completing the course

Get Started
Advertisements