基础知识要求:
java:方法、字符串、if 语句、for循环、逻辑运算符、二维数组
python: 方法、字符串、if else语句、for循环、逻辑运算符、二维数组
题目:
给你一个字符串 s
,找到 s
中最长的回文子串。
如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。
示例 1:
输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
示例 2:
输入:s = "cbbd" 输出:"bb"
提示:
1 <= s.length <= 1000
s
仅由数字和英文字母组成
Java代码示例 :
public class LongestPalindromeSubstring {
/**
* 找到给定字符串中的最长回文子串
*
* @param s 输入的字符串
* @return 最长的回文子串
*/
public static String longestPalindrome(String s) {
if (s == null || s.length() < 1) {
return ""; // 如果字符串为空或长度小于1,则返回空字符串
}
int n = s.length();
boolean[][] dp = new boolean[n][n]; // 创建一个二维数组来存储子字符串是否是回文的信息
int start = 0, end = 0; // 存储最长回文子串的起始和结束索引
// 遍历所有可能的子字符串
for (int right = 0; right < n; right++) {
for (int left = 0; left <= right; left++) {
// 如果首尾字符相同,并且去掉首尾的子字符串也是回文的(或者子字符串长度小于等于2),则当前子字符串是回文的
if (s.charAt(left) == s.charAt(right) && (right - left <= 2 || dp[left + 1][right - 1])) {
dp[left][right] = true; // 更新dp数组
// 如果当前回文子串长度大于之前找到的最长回文子串长度,则更新最长回文子串的起始和结束索引
if (right - left + 1 > end - start) {
start = left;
end = right;
}
}
}
}
// 从原始字符串中提取最长回文子串并返回
return s.substring(start, end + 1);
}
/**
* 主方法,用于测试longestPalindrome方法
*
* @param args 命令行参数
*/
public static void main(String[] args) {
String s = "babad";
System.out.println(longestPalindrome(s)); // 输出:"bab" 或 "aba"
s = "cbbd";
System.out.println(longestPalindrome(s)); // 输出:"bb"
}
}
这段代码定义了一个longestPalindrome
方法,它接受一个字符串s
作为输入,并返回最长的回文子串。它首先检查字符串是否为空或长度小于1,如果是,则返回空字符串。然后,它创建一个二维布尔数组dp
来存储子字符串是否是回文的信息。数组dp[i][j]
表示从索引i
到j
的子字符串是否是回文的。
接下来,代码使用两个嵌套的循环来遍历所有可能的子字符串。对于每个子字符串,它检查首尾字符是否相等,并且去掉首尾字符的子字符串(如果存在)是否也是回文的。如果是,那么当前子字符串就是回文的,并且更新dp[i][j]
为true
。同时,它还检查当前回文子串的长度是否大于之前找到的最长回文子串的长度,并更新最长回文子串的起始和结束索引。
最后,代码使用substring
方法从原始字符串中提取最长回文子串,并将其返回。
在main
方法中,我们提供了两个示例字符串来测试longestPalindrome
方法,并打印出结果。
Python代码示例:
def longestPalindrome(s: str) -> str:
n = len(s)
if n < 2:
return s
# 初始化动态规划数组
# dp[i][j] 表示 s[i:j+1] 是否是回文串
dp = [[False] * n for _ in range(n)]
# 初始化单个字符都是回文串
for i in range(n):
dp[i][i] = True
# 最长回文子串的起始和结束索引
start, end = 0, 0
# 从子串长度为2开始检查回文串
for length in range(2, n + 1):
# 遍历所有长度为 length 的子串
for i in range(n - length + 1):
j = i + length - 1
# 当子串长度为2时,比较两个字符是否相同
if length == 2:
dp[i][j] = s[i] == s[j]
else:
# 如果首尾字符相同,并且去掉首尾的子串也是回文串,则当前子串是回文串
dp[i][j] = s[i] == s[j] and dp[i + 1][j - 1]
# 更新最长回文子串的起始和结束索引
if dp[i][j] and j - i + 1 > end - start:
start, end = i, j
# 返回最长回文子串
return s[start:end + 1]
# 示例
s = "babad"
print(longestPalindrome(s)) # 输出: "bab" 或 "aba"
s = "cbbd"
print(longestPalindrome(s)) # 输出: "bb"
这段代码首先初始化了一个二维数组 dp
来存储回文子串的信息,然后通过两层循环遍历所有可能的子串,判断它们是否是回文的,并更新最长回文子串的起始和结束索引。最后返回最长回文子串。
值得注意的是,上述代码返回的是最长回文子串的其中一个解,因为可能存在多个最长回文子串。例如,对于输入 "babad",返回 "bab" 或 "aba" 都是正确的。