随笔 - 121  文章 - 0  评论 - 0  阅读 - 24269

力扣5. 最长回文子串(双指针、dp)

给你一个字符串 s,找到 s 中最长的回文子串。

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

 

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。

 

示例 2:

输入:s = "cbbd"
输出:"bb"

 

提示:

  • 1 <= s.length <= 1000
  • s 仅由数字和英文字母组成

 

该题的状态转移比较好想到,难点在于如何去填充dp数组。以往dp数组都是一行一行的更新,但在这道题中,dp[i][j]可能用到的是dp[i+1][j-1]的状态,而dp[i+1][j-1]这个状态要在下一层才会被更新,也就是说不能以行为单位进行更新,得以另外一种形式(也不是单纯的以列为单位)进行更新,具体的形式是外层循环控制右边界,内层循环控制左边界。当然,该题还有其他动态规划的解法。

复制代码
 1 class Solution {
 2     bool dp[1005][1005]; //dp[i][j]表示字符串S(i,j)的是否为回文子串
 3 public:
 4     bool judge(string s){
 5         int head=0,tail=s.size()-1;
 6         while(head<=tail){
 7             if (s[head]!=s[tail])
 8                 return false;
 9             head++;
10             tail--;
11         }
12         return true;
13     }
14     string longestPalindrome(string s) {
15         memset(dp,false,sizeof(dp));
16         int max_head=0;  //最大子串的首字符
17         int mmax=1;  //最大子串长度
18         for (int r=1;r<s.size();++r){  //l表示左边界,r表示右边界
19             for (int l=0;l<r;++l){
20                 if (s[l]!=s[r]){  //字符串S(i,j)的两端相等才进一步判断是否为回文串
21                     continue;
22                 }else{
23                     if ((r-1)-(l+1)+1<=1){  //若字符串S(l+1,r-1)的长度为0或1,则直接是回文
24                         dp[l][r]=true;
25                     }else{  //状态转移
26                         dp[l][r]=dp[l+1][r-1];
27                     }
28                     if (dp[l][r]&&r-l+1>mmax){  //更新最大子串信息
29                         max_head=l;
30                         mmax=r-l+1;
31                     }                
32                 }
33             }
34         }
35         return s.substr(max_head,mmax);
36     }
37 };
复制代码

 双指针法:主要考虑到回文串奇数与偶数时的不同,奇数的字符串中心是单字符,偶数的字符串中心是两个相同字符。

复制代码
 1 class Solution {
 2 public:
 3     string findPalindrome(int i, int j, string s){
 4         while(i >= 0 && j < s.size() && s[i] == s[j]) {
 5             i--;
 6             j++;
 7         }
 8         return s.substr(i + 1, j - i - 1);
 9     }
10     string longestPalindrome(string s) {
11         string res = "";
12         for (int i = 0; i < s.size(); ++i) {
13             // 假设回文串为奇数长度,则以s[i]为中心
14             string temp = findPalindrome(i, i, s);
15             res = res.size() < temp.size() ? temp:res;
16             // 假设回文串为偶数长度,则以s[i]和s[i+1]为中心
17             temp = findPalindrome(i, i + 1, s);
18             res = res.size() < temp.size() ? temp:res;
19         }
20         return res;
21     }
22 };
复制代码

 

posted on   Coder何  阅读(14)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列1:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· Apache Tomcat RCE漏洞复现(CVE-2025-24813)
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5

点击右上角即可分享
微信分享提示