leetcode5最:长回文子串
动态规划:
1个回文串,两边加上同样的字符,也是回文串。这是一个性质,之后要用。
对于一大串字符,从1长度的子串开始判断。
1个长度的子串,肯定回文;如果这个子串两边加上同样的字符,长度变成了3,少了一次判断。
因此还要加上,判断2长度的子串是不是回文。
之后才会判断3长度的子串是不是回文。
以此类推。
看图说明,假设有这么一个字符串“abbab"
列一个二维数据表,这个表存储了所有子串的情况。如下。
| a | ab | abb | abba | abbab |
| b | bb | bba | bbab | |
| b | ba | bab | ||
| a | ab | |||
| b |
我们就是从第一个对角线开始判断
已知1长度子串肯定回文,又单独判断了2长度的子串是不是回文,对应一个这样的表。(1表示回文,0表示不回文)
| 1 | 0 | |||
| 1 | 1 | |||
| 1 | 0 | |||
| 1 | 0 | |||
| 1 |
那么3长度的子串是不是回文,用一下回文的性质。
3长度,看它首尾是否相等,中间字串是否回文。
4长度,看它首尾是否相等,中间字串是否回文。
首尾字符是否相等这个判断很简单,而它中间的字串是否回文,取决于我们之前算的这个表。
比如0,3位置的子串“abb”是否回文,取决于"a"和“b"以及中间子串b ,而"b"之前已经算过了;只需要额外判断一下"a","b"即可。
转换成动态转移方程 str(begin,end)=str(begin+1)(end-1)&&s[begin]==s[end];
因此这个表出来了
| 1 | 0 | 0 | 1 | 0 |
| 1 | 1 | 0 | 0 | |
| 1 | 0 | 1 | ||
| 1 | 0 | |||
| 1 |
代码如下:
class Solution { public: string longestPalindrome(string s) { if (s.size()<2) return s; vector<vector<int>> dp(s.size(),vector<int>(s.size(),0)); string ans=s.substr(0,1); for(int i=0;i<s.size();i++) { dp[i][i]=1; } for(int i=0;i<s.size()-1;i++) { if(s[i]==s[i+1]) { dp[i][i+1]=1; ans=s.substr(i,2); } } for(int length=2;length<=s.size();length++) { for(int i=0;i<s.size()-length+1;i++) { if(dp[i+1][i+length-2]==1&&s[i]==s[i+length-1]) { dp[i][i+length-1]=1; ans=s.substr(i,length); } } } return ans; } };
问题是空间复杂度和时间复杂度都是O(N2)
更优的解法之后更新。
posted on 2023-06-23 22:03 WhatAnyWay 阅读(14) 评论(0) 收藏 举报
浙公网安备 33010602011771号