LeetCode:最长回文子串(动态规划)
创始人
2024-05-29 07:06:39
0

一、题目

在这里插入图片描述
https://leetcode.cn/problems/longest-palindromic-substring/description/

二、 算法思想

使用动态规划思想解决,如果一个子串是回文的,并且它的左右两边各加上一个字符后仍然是回文的,那么这个子串加上这两个字符后也一定是回文的。因此可以用一个二维数组记录每个子串是否是回文的,然后逐步扩展子串的长度,直到找到最长的回文子串。

假设要判断 s[i…j] 是否是回文的,那么只需要判断 s[i+1…j-1] 是否是回文的,并且 s[i] == s[j],即可判断 s[i…j] 是否是回文的。因此可以用一个二维数组 dp[i][j] 表示 s[i…j] 是否是回文的,如果是回文的,dp[i][j] 的值为 true,否则为 false。初始化时,单个字符肯定是回文的,因此 dp[i][i] 的值都为 true。

然后逐步扩展子串的长度,如果 s[i+1…j-1] 是回文的,并且 s[i] == s[j],那么 s[i…j] 也是回文的,即 dp[i][j] = true。最后找到所有 dp[i][j] 为 true 的子串中长度最长的即可。

C++代码中,使用一个二维数组dp来存储每个子串是否为回文串的状态,其中dp[i][j]表示字符串s从下标i到下标j的子串是否为回文串。初始化时,所有状态都为0。
接下来,枚举所有可能的子串,从长度为1到n,依次计算每个子串是否为回文串,更新dp数组和最长回文子串的长度和起始位置。最后返回最长回文子串即可。

Java 代码实现

class Solution {public String longestPalindrome(String s) {int n = s.length();boolean[][] dp = new boolean[n][n];String res = "";for (int len = 1; len <= n; len++) {    //len是回文子串长度for (int i = 0; i + len - 1 < n; i++) {int j = i + len - 1;    //回文子串的右边界if (len == 1) {         // 单个字符是回文串dp[i][j] = true;} else if (len == 2) {      // 两个字符相等就是回文串dp[i][j] = s.charAt(i) == s.charAt(j);} else {        // 状态转移方程dp[i][j] = dp[i+1][j-1] && s.charAt(i) == s.charAt(j);}if (dp[i][j] && len > res.length()) {   // 更新最长回文子串res = s.substring(i, j+1);}}}return res;}
}

C++代码实现

class Solution {
public:
string longestPalindrome(string s) {int n = s.size();//创建一个n*n的二维矩阵(即一个二维向量),其中每个元素是一个整数。vector> dp(n, vector(n)); // 初始化为0int start = 0, maxLen = 1;// 枚举所有可能的子串,从长度为1到nfor (int len = 1; len <= n; ++len) {for (int i = 0; i + len - 1 < n; ++i) {int j = i + len - 1; // 子串右端点if (len == 1) {dp[i][j] = 1; // 单个字符是回文串} else if (len == 2) {dp[i][j] = (s[i] == s[j]); // 两个字符相等就是回文串} else {dp[i][j] = (s[i] == s[j] && dp[i+1][j-1]); // 状态转移方程}if (dp[i][j] && len > maxLen) { // 更新最长回文子串的长度和起始位置start = i;maxLen = len;}}}return s.substr(start, maxLen); // 返回最长回文子串}
};

三、算法时间空间复杂度分析

Java代码

算法的时间复杂度为 O(n2)O(n^2)O(n2),其中 nnn 是字符串的长度。这是因为算法中使用了一个二维数组 dpdpdp,该数组的大小为 n×nn \times nn×n,且算法需要填充该数组的所有元素。对于每个元素 (i,j)(i,j)(i,j),需要使用 O(1)O(1)O(1) 的时间计算其值。

算法的空间复杂度也是 O(n2)O(n^2)O(n2)。这是因为算法中使用了一个二维数组 dpdpdp,该数组的大小为 n×nn \times nn×n。除此之外,算法还使用了一个字符串变量 resresres,其长度不超过 nnn。因此,该算法的总空间复杂度为 O(n2)O(n^2)O(n2)。

C++代码

算法的时间复杂度为O(n2)O(n^2)O(n2),空间复杂度也为O(n2)O(n^2)O(n2)。

相关内容

热门资讯

喜欢穿一身黑的男生性格(喜欢穿... 今天百科达人给各位分享喜欢穿一身黑的男生性格的知识,其中也会对喜欢穿一身黑衣服的男人人好相处吗进行解...
发春是什么意思(思春和发春是什... 本篇文章极速百科给大家谈谈发春是什么意思,以及思春和发春是什么意思对应的知识点,希望对各位有所帮助,...
网络用语zl是什么意思(zl是... 今天给各位分享网络用语zl是什么意思的知识,其中也会对zl是啥意思是什么网络用语进行解释,如果能碰巧...
为什么酷狗音乐自己唱的歌不能下... 本篇文章极速百科小编给大家谈谈为什么酷狗音乐自己唱的歌不能下载到本地?,以及为什么酷狗下载的歌曲不是...
华为下载未安装的文件去哪找(华... 今天百科达人给各位分享华为下载未安装的文件去哪找的知识,其中也会对华为下载未安装的文件去哪找到进行解...
怎么往应用助手里添加应用(应用... 今天百科达人给各位分享怎么往应用助手里添加应用的知识,其中也会对应用助手怎么添加微信进行解释,如果能...
家里可以做假山养金鱼吗(假山能... 今天百科达人给各位分享家里可以做假山养金鱼吗的知识,其中也会对假山能放鱼缸里吗进行解释,如果能碰巧解...
四分五裂是什么生肖什么动物(四... 本篇文章极速百科小编给大家谈谈四分五裂是什么生肖什么动物,以及四分五裂打一生肖是什么对应的知识点,希...
一帆风顺二龙腾飞三阳开泰祝福语... 本篇文章极速百科给大家谈谈一帆风顺二龙腾飞三阳开泰祝福语,以及一帆风顺二龙腾飞三阳开泰祝福语结婚对应...
美团联名卡审核成功待激活(美团... 今天百科达人给各位分享美团联名卡审核成功待激活的知识,其中也会对美团联名卡审核未通过进行解释,如果能...