Expand Around Center
Intuition
Every palindrome has a center — either a single character (odd length) or a pair of adjacent characters (even length). We can find the longest palindrome by trying each possible center and expanding outward as long as the characters on both sides match. This gives us at most 2n - 1 centers to check (n for odd-length, n-1 for even-length palindromes), and each expansion takes O(n) time in the worst case.
Algorithm
- Initialize variables to track the start index and maximum length of the longest palindrome found.
- For each index `i` in the string, expand around center for both odd-length (`left = i, right = i`) and even-length (`left = i, right = i + 1`) palindromes.
- For each center, expand outward while `left >= 0`, `right < n`, and `s[left] == s[right]`.
- After expansion, if the palindrome length is greater than the current maximum, update the start index and maximum length.
- Return the substring from start to start + maxLength.
O(n^2)SpaceO(1)Code (C++ · Java · Python · Go)
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size();
if (n < 2) return s;
int start = 0, maxLen = 1;
auto expand = [&](int left, int right) {
while (left >= 0 && right < n && s[left] == s[right]) {
if (right - left + 1 > maxLen) {
start = left;
maxLen = right - left + 1;
}
left--;
right++;
}
};
for (int i = 0; i < n; i++) {
expand(i, i);
expand(i, i + 1);
}
return s.substr(start, maxLen);
}
};class Solution {
public String longestPalindrome(String s) {
int n = s.length();
if (n < 2) return s;
int start = 0, maxLen = 1;
for (int i = 0; i < n; i++) {
int len1 = expand(s, i, i);
int len2 = expand(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > maxLen) {
maxLen = len;
start = i - (len - 1) / 2;
}
}
return s.substring(start, start + maxLen);
}
private int expand(String s, int left, int right) {
while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) {
left--;
right++;
}
return right - left - 1;
}
}class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s)
if n < 2:
return s
start, max_len = 0, 1
def expand(left: int, right: int) -> None:
nonlocal start, max_len
while left >= 0 and right < n and s[left] == s[right]:
if right - left + 1 > max_len:
start = left
max_len = right - left + 1
left -= 1
right += 1
for i in range(n):
expand(i, i)
expand(i, i + 1)
return s[start:start + max_len]func longestPalindrome(s string) string {
n := len(s)
if n < 2 {
return s
}
start, maxLen := 0, 1
expand := func(left, right int) {
for left >= 0 && right < n && s[left] == s[right] {
if right-left+1 > maxLen {
start = left
maxLen = right - left + 1
}
left--
right++
}
}
for i := 0; i < n; i++ {
expand(i, i)
expand(i, i+1)
}
return s[start : start+maxLen]
}