Want Help Cracking FAANG?

(Then click this)

×
Back to Question Bank

1328. Break a Palindrome - Leetcode Solution

Code Implementation

class Solution:
    def breakPalindrome(self, palindrome: str) -> str:
        n = len(palindrome)
        if n == 1:
            return ""
        chars = list(palindrome)
        for i in range(n // 2):
            if chars[i] != 'a':
                chars[i] = 'a'
                return "".join(chars)
        chars[-1] = 'b'
        return "".join(chars)
      
class Solution {
public:
    string breakPalindrome(string palindrome) {
        int n = palindrome.size();
        if (n == 1) return "";
        for (int i = 0; i < n / 2; ++i) {
            if (palindrome[i] != 'a') {
                palindrome[i] = 'a';
                return palindrome;
            }
        }
        palindrome[n - 1] = 'b';
        return palindrome;
    }
};
      
class Solution {
    public String breakPalindrome(String palindrome) {
        int n = palindrome.length();
        if (n == 1) return "";
        char[] chars = palindrome.toCharArray();
        for (int i = 0; i < n / 2; i++) {
            if (chars[i] != 'a') {
                chars[i] = 'a';
                return new String(chars);
            }
        }
        chars[n - 1] = 'b';
        return new String(chars);
    }
}
      
var breakPalindrome = function(palindrome) {
    if (palindrome.length === 1) return "";
    let arr = palindrome.split('');
    for (let i = 0; i < Math.floor(arr.length / 2); i++) {
        if (arr[i] !== 'a') {
            arr[i] = 'a';
            return arr.join('');
        }
    }
    arr[arr.length - 1] = 'b';
    return arr.join('');
};
      

Problem Description

You are given a palindromic string palindrome consisting of lowercase English letters. Your task is to replace exactly one character in the string so that the resulting string is not a palindrome and is the lexicographically smallest possible among all such results. If it is impossible to achieve this (for example, if the string's length is 1), return an empty string "".

  • Only one character can be replaced.
  • The new string must not be a palindrome.
  • The result should be the lexicographically smallest possible (alphabetical order).
  • If no valid answer exists, return "".

Thought Process

At first glance, it may seem that we need to try changing every character in the palindrome and check if the resulting string is still a palindrome. However, this brute-force approach would be inefficient, especially for longer strings.

Instead, let's think about what makes a string the lexicographically smallest. For English lowercase letters, 'a' is the smallest. So, to make the smallest string, we want the leftmost character that is not 'a' to become 'a'. However, we also need to make sure the string is no longer a palindrome after the change.

For palindromes, changing a character in the first half will always break the symmetry, except for the middle character in odd-length strings (since it mirrors itself). So, we only need to look at the first half of the string for a character to change.

If all characters in the first half are already 'a', the only way to break the palindrome is to change the last character (which is mirrored in the first half) to 'b', the next smallest letter.

Solution Approach

  • Step 1: If the string length is 1, it's impossible to break the palindrome by changing one character. Return "".
  • Step 2: Convert the string to an array (or character array) for easy modification.
  • Step 3: Iterate over the first half of the array:
    • If you find a character that is not 'a', change it to 'a' and return the modified string. This is because changing the leftmost non-'a' character to 'a' will yield the lexicographically smallest result and break the palindrome.
  • Step 4: If all characters in the first half are 'a', then change the last character to 'b'. This guarantees the string is not a palindrome, and 'b' is the next smallest letter after 'a'.
  • Step 5: Return the modified string.

This approach is efficient because it only examines up to half the string and makes a single change.

Example Walkthrough

Let's use the input palindrome = "abccba" as an example.

  • Length is 6, so we check the first 3 characters: 'a', 'b', 'c'.
  • First character is 'a' (already the smallest).
  • Second character is 'b' (not 'a'). Change it to 'a'.
  • The new string is "aaccba".
  • Is "aaccba" a palindrome? No (because "aaccba" != "abccba" reversed).
  • This is the lexicographically smallest string possible after breaking the palindrome with one change.

Another example: palindrome = "aabaa"

  • Length is 5, check first 2 characters: 'a', 'a'.
  • Both are 'a', so change the last character to 'b'.
  • The new string is "aabab".
  • It's not a palindrome and is lexicographically smallest.

Time and Space Complexity

  • Brute-force approach: Try every character replacement and check if the result is a palindrome. This is O(N^2), since for each of N positions, we may create a new string and check for palindrome status (which is O(N)).
  • Optimized approach (this solution):
    • Time Complexity: O(N), where N is the length of the string. We only loop through half the string at most.
    • Space Complexity: O(N), due to creating a character array (or new string) for manipulation.

The optimized approach is much faster and uses minimal extra space.

Summary

The key to solving "Break a Palindrome" efficiently is to recognize that the lexicographically smallest string is achieved by changing the leftmost non-'a' character to 'a', but only in the first half of the palindrome. If all such characters are already 'a', changing the last character to 'b' is the best alternative. This strategy avoids unnecessary computation and ensures the result is both valid and optimal.