题目描述
给你一个字符串 s
,找到 s
中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd" 输出:"bb"
提示:
1 <= s.length <= 1000
s
仅由数字和英文字母组成
解法
方法一:动态规划
这段代码是实现的寻找字符串中最长回文子串的函数。这个函数首先创建一个二维布尔数组f
,然后通过两层循环比较字符串中每个字符的对称位置的字符是否相等,如果相等则更新f[i][j]
为f[i+1][j-1]
的值。同时,如果当前字符相等并且找到的回文子串长度大于当前最大长度,则更新最大长度以及起始位置。最后,返回从起始位置到结束位置的子串作为结果。
这段代码的主要逻辑是:
- 初始化一个二维布尔数组
f
,所有元素都为true
。这个数组用来存储以每个位置为结尾的回文子串的状态,如果以该位置为结尾的回文子串存在,则对应的状态为true
,否则为false
。 - 通过两层循环遍历字符串中的所有字符对。外层循环从字符串的倒数第二个字符开始,内层循环从外层循环的下一个字符开始。
- 对于每个字符对,首先判断两个字符是否相等。如果相等,则说明当前字符对可能是一个回文子串的一部分。然后判断以当前字符为结尾的回文子串是否已经存在。如果存在,则说明当前字符对确实是一个回文子串的一部分。同时,如果找到的回文子串长度大于当前最大长度,则更新最大长度以及起始位置。
- 最后,返回从起始位置到结束位置的子串作为结果。
需要注意的是,这个算法的时间复杂度是O(n^2),空间复杂度也是O(n^2)。
c++
#include <string>
#include <vector>
#include <iostream>
using namespace std;
class Solution {
public:
string longestPalindrome(string s) {
int n = s.size(); // 获取字符串s的长度
vector<vector<bool>> f(n, vector<bool>(n, true)); // 创建一个二维布尔型数组f,用来记录子串是否为回文子串
int k = 0, mx = 1; // 初始化变量k和mx,分别表示最长回文子串的起始位置和长度
for (int i = n - 2; ~i; --i) { // 从字符串末尾开始向前遍历
for (int j = i + 1; j < n; ++j) { // 遍历所有可能的子串
f[i][j] = false; // 先假设当前子串不是回文子串
if (s[i] == s[j]) { // 如果头尾字符相同
f[i][j] = f[i + 1][j - 1]; // 判断去掉头尾字符后的子串是否为回文子串
if (f[i][j] && mx < j - i + 1) { // 如果当前子串为回文子串且长度大于之前记录的最长回文子串长度
mx = j - i + 1; // 更新最长回文子串的长度
k = i; // 更新最长回文子串的起始位置
}
}
}
}
return s.substr(k, mx); // 返回最长回文子串
}
};
int main()
{
Solution sol;
string input = "babad";
string result = sol.longestPalindrome(input);
cout << result << endl;
}
C#
public class Solution
{
public string LongestPalindrome(string s)
{
int n = s.Length; // 获取字符串s的长度
bool[,] f = new bool[n, n]; // 创建一个二维布尔型数组f,用来记录子串是否为回文子串
for (int i = 0; i < n; i++)
{ // 初始化二维数组f,使得所有长度为1的子串都是回文子串
for (int j = 0; j < n; ++j)
{
f[i, j] = true;
}
}
int k = 0, mx = 1; // 初始化变量k和mx,分别表示最长回文子串的起始位置和长度
for (int i = n - 2; i >= 0; --i)
{ // 从字符串末尾开始向前遍历
for (int j = i + 1; j < n; ++j)
{ // 遍历所有可能的子串
f[i, j] = false; // 先假设当前子串不是回文子串
if (s[i] == s[j])
{ // 如果头尾字符相同
f[i, j] = f[i + 1, j - 1]; // 判断去掉头尾字符后的子串是否为回文子串
if (f[i, j] && mx < j - i + 1)
{ // 如果当前子串为回文子串且长度大于之前记录的最长回文子串长度
mx = j - i + 1; // 更新最长回文子串的长度
k = i; // 更新最长回文子串的起始位置
}
}
}
}
return s.Substring(k, mx); // 返回最长回文子串
}
static void Main(string[] args)
{
Solution sol = new Solution(); // 创建Solution类的实例
string input = "babad"; // 输入字符串
string result = sol.LongestPalindrome(input); // 调用LongestPalindrome函数寻找最长回文子串
Console.WriteLine("Longest Palindromic Substring: " + result); // 打印结果
}
}
Python
class Solution:
def longestPalindrome(self, s: str) -> str:
n = len(s) # 获取字符串s的长度
f = [[True] * n for _ in range(n)] # 创建一个二维布尔型列表f,用来记录子串是否为回文子串
k, mx = 0, 1 # 初始化变量k和mx,分别表示最长回文子串的起始位置和长度
for i in range(n - 2, -1, -1): # 从字符串末尾开始向前遍历
for j in range(i + 1, n): # 遍历所有可能的子串
f[i][j] = False # 先假设当前子串不是回文子串
if s[i] == s[j]: # 如果头尾字符相同
f[i][j] = f[i + 1][j - 1] # 判断去掉头尾字符后的子串是否为回文子串
if f[i][j] and mx < j - i + 1: # 如果当前子串为回文子串且长度大于之前记录的最长回文子串长度
k, mx = i, j - i + 1 # 更新最长回文子串的起始位置和长度
return s[k : k + mx] # 返回最长回文子串
# 创建Solution类的实例
sol = Solution()
# 输入字符串
input_str = "babad"
# 调用longestPalindrome函数寻找最长回文子串
result = sol.longestPalindrome(input_str)
# 打印结果
print("Longest Palindromic Substring:", result)
Java
import java.util.Arrays;
class Solution {
public String longestPalindrome(String s) {
int n = s.length(); // 获取字符串s的长度
boolean[][] f = new boolean[n][n]; // 创建一个二维布尔型数组f,用来记录子串是否为回文子串
for (var g : f) { // 遍历二维数组f的每一行
Arrays.fill(g, true); // 将当前行填充为true,表示初始时所有子串都被认为是回文子串
}
int k = 0, mx = 1; // 初始化变量k和mx,分别表示最长回文子串的起始位置和长度
for (int i = n - 2; i >= 0; --i) { // 从字符串末尾开始向前遍历
for (int j = i + 1; j < n; ++j) { // 遍历所有可能的子串
f[i][j] = false; // 先假设当前子串不是回文子串
if (s.charAt(i) == s.charAt(j)) { // 如果头尾字符相同
f[i][j] = f[i + 1][j - 1]; // 判断去掉头尾字符后的子串是否为回文子串
if (f[i][j] && mx < j - i + 1) { // 如果当前子串为回文子串且长度大于之前记录的最长回文子串长度
mx = j - i + 1; // 更新最长回文子串的长度
k = i; // 更新最长回文子串的起始位置
}
}
}
}
return s.substring(k, k + mx); // 返回最长回文子串
}
public static void main(String[] args) {
Solution sol = new Solution(); // 创建Solution类的实例
String input_str = "babad"; // 输入字符串
String result = sol.longestPalindrome(input_str); // 调用longestPalindrome函数寻找最长回文子串
System.out.println("Longest Palindromic Substring: " + result); // 打印结果
}
}