1328. Break a Palindrome
Description
Given a palindromic string of lowercase English letters palindrome
, replace exactly one character with any lowercase English letter so that the resulting string is not a palindrome and that it is the lexicographically smallest one possible.
Return the resulting string. If there is no way to replace a character to make it not a palindrome, return an empty string.
A string a
is lexicographically smaller than a string b
(of the same length) if in the first position where a
and b
differ, a
has a character strictly smaller than the corresponding character in b
. For example, "abcc"
is lexicographically smaller than "abcd"
because the first position they differ is at the fourth character, and 'c'
is smaller than 'd'
.
Example 1:
Input: palindrome = "abccba" Output: "aaccba" Explanation: There are many ways to make "abccba" not a palindrome, such as "zbccba", "aaccba", and "abacba". Of all the ways, "aaccba" is the lexicographically smallest.
Example 2:
Input: palindrome = "a" Output: "" Explanation: There is no way to replace a single character to make "a" not a palindrome, so return an empty string.
Constraints:
1 <= palindrome.length <= 1000
palindrome
consists of only lowercase English letters.
Solutions
Solution 1: Greedy
First, we check if the length of the string is $1$. If it is, we directly return an empty string.
Otherwise, we traverse the first half of the string from left to right, find the first character that is not 'a'
, and change it to 'a'
. If no such character exists, we change the last character to 'b'
.
The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the length of the string.
Python3
class Solution:
def breakPalindrome(self, palindrome: str) -> str:
n = len(palindrome)
if n == 1:
return ""
s = list(palindrome)
i = 0
while i < n // 2 and s[i] == "a":
i += 1
if i == n // 2:
s[-1] = "b"
else:
s[i] = "a"
return "".join(s)
Java
class Solution {
public String breakPalindrome(String palindrome) {
int n = palindrome.length();
if (n == 1) {
return "";
}
char[] s = palindrome.toCharArray();
int i = 0;
while (i < n / 2 && s[i] == 'a') {
++i;
}
if (i == n / 2) {
s[n - 1] = 'b';
} else {
s[i] = 'a';
}
return String.valueOf(s);
}
}
C++
class Solution {
public:
string breakPalindrome(string palindrome) {
int n = palindrome.size();
if (n == 1) {
return "";
}
int i = 0;
while (i < n / 2 && palindrome[i] == 'a') {
++i;
}
if (i == n / 2) {
palindrome[n - 1] = 'b';
} else {
palindrome[i] = 'a';
}
return palindrome;
}
};
Go
func breakPalindrome(palindrome string) string {
n := len(palindrome)
if n == 1 {
return ""
}
i := 0
s := []byte(palindrome)
for i < n/2 && s[i] == 'a' {
i++
}
if i == n/2 {
s[n-1] = 'b'
} else {
s[i] = 'a'
}
return string(s)
}
TypeScript
function breakPalindrome(palindrome: string): string {
const n = palindrome.length;
if (n === 1) {
return '';
}
const s = palindrome.split('');
let i = 0;
while (i < n >> 1 && s[i] === 'a') {
i++;
}
if (i == n >> 1) {
s[n - 1] = 'b';
} else {
s[i] = 'a';
}
return s.join('');
}
Rust
impl Solution {
pub fn break_palindrome(palindrome: String) -> String {
let n = palindrome.len();
if n == 1 {
return "".to_string();
}
let mut s: Vec<char> = palindrome.chars().collect();
let mut i = 0;
while i < n / 2 && s[i] == 'a' {
i += 1;
}
if i == n / 2 {
s[n - 1] = 'b';
} else {
s[i] = 'a';
}
s.into_iter().collect()
}
}