5. Longest Palindromic Substring[M]最长回文子串
题目
Given a string s, find the longest palindromic substring in s. You may assume that the maximum length of s is 1000.
Example1:
Input: "babad"
Output: "bab"
Note: "aba is also a valid answer. "
Example2:
Input: "cbbd"
Output: "bb"
思路
思路1:动态规划
Step1:刻画一个最优解方程
\(dp[i][j]\)表示子串\(s[i, \cdots,j]\)是否是一个回文子串
Step2:递归定义最优解的值
(1)初始化:
- dp[i][i] = true, i = [0, 1, ... ,n-1];
- dp[i][i-1] = true, i = [1,2,...,n-1]
- 其余为false
(2)状态转移表
- dp[i][j] = (s[i] == s[j] && dp[i+1][j-1])
状态转移表更新如图1:
Step3:计算最优解的值
根据状态转移表,以及递推公式,计算dp[i][j]。
思路2:中心扩展法
以某字符为中心,分别计算回文长度。分为回文子串为奇数、偶数两种情况
- 奇数:以当前遍历字符为中心判断
- 偶数:以当前遍历字符与其相邻字符为中心判断
思路3:Manacher算法
又称为马拉车算法,可以在时间复杂都为O(n)的情况下求解一个字符串的最长回文子串的问题。
Manacher算法通过为字符串虚拟增加#(并不是真的增加#),使得长度为奇数和长度为偶数的回文子串放在一起考虑(使得回文子串长度都为奇数),如图1。具体操作:在字符串的首部、尾部、相邻字符之间虚拟增加#号。
(1)Len数组的性质
(2)Len数组的计算
思路4:字符串分片(python)
利用字符串的分片操作来检测是否是回文。
Tips
动态规划
将待求解问题分解为若干个非互相独立的子问题,先求子问题,再求原问题。(通常需要将不同阶段的不同状态保存在二维数组内)。
C++
- 思路1
class Solution {
public:
string longestPalindrome(string s) {
int nLength = s.size();
if(nLength<1)
return s;
vector<vector<bool> > dp(nLength, vector<bool>(nLength, 0)); //dp[i][j]表示子串s[i,...,j]是否是一个回文子串
int strBegin = 0; //回文子串的开始
int strEnd = 0; //回文子串的结尾
//初始化
for(int i = 1;i < nLength; i++){
dp[i][i] = true;
dp[i][i-1] = true; //这个是针对子串长度为2,"bb"、"aa"的情况
}
dp[0][0] = true;
//动态规划
for(int i = 2;i <= nLength; i++){ //回文长度
for(int j = 0; j <= nLength - i ; j++){ //回文子串起始
if(s[j] == s[i+j - 1] && dp[j+1][i+j-2]){
dp[j][j+i-1] = true;
if(strEnd - strBegin + 1 < i){
strBegin = j;
strEnd = i + j -1;
}
}
}
}
return s.substr(strBegin,strEnd-strBegin+1);
}
};
- 思路2
class Solution {
public:
string longestPalindrome(string s) {
int nLength = s.size();
if(nLength == 1)
return s;
int strBegin = 0;
int maxLength = 0;
for(int i = 1;i < nLength; i++){
//如果回文子串是奇数,以i为中心搜索
int left = i - 1;
int right = i + 1;
while(left >=0 && right < nLength && s[left] == s[right] )
{
left --;
right ++;
}
if(right - left - 1 > maxLength){ //right -1 - (left + 1) + 1
maxLength = right - left - 1;
strBegin = left + 1;
}
//如果回文子串是偶数,
left = i - 1;
right = i;
while(left >=0 && right < nLength && s[left] == s[right]){
left --;
right ++;
}
if(right - left - 1 > maxLength){
maxLength = right - left - 1;
strBegin = left + 1;
}
}
return s.substr(strBegin,maxLength);
}
};
- 思路3
class Solution {
public:
string longestPalindrome(string s) {
if(s.size() <= 1)
return s;
string dummy = init(s);
int nLength = dummy.size();
int maxLen = 0;
int mx = 0;
int id = 0;
vector<int> len(nLength, 0);
for(int i =1;i< nLength - 1; i++){
if(i < mx)
len[i] = min(len[2*id -i], mx - i);
else
len[i] = 1;
while(dummy[i - len[i]] == dummy[i + len[i]])
len[i] ++;
if(mx < i + len[i]){
id = i;
mx = i + len[i];
}
}
int index = 0;
for(int i = 1; i < nLength-1; i++){
if(len[i] > maxLen){
maxLen = len[i];
index = i;
}
}
return s.substr((index - maxLen)/2, maxLen-1);
}
//初始化
string init(const string& s){
string result = "$#";
int nLength = s.size();
for(int i=0;i < nLength; i++){
result.push_back(s[i]);
result.push_back('#');
}
return result;
}
};
Python
class Solution(object):
def longestPalindrome(self, s):
"""
:type s: str
:rtype: str
"""
if len(s) == 1:
return s
result = ""
for i in range(len(s)):
j = i + 1
while j <= len(s) and len(result) <= len(s[i:]):
if s[i:j] == s[i:j][::-1] and len(s[i:j]) > len(result):
result = s[i:j]
j += 1
return result
参考
[1] https://blog.csdn.net/suool/article/details/38383045
5. Longest Palindromic Substring[M]最长回文子串的更多相关文章
- 21.Longest Palindromic Substring(最长回文子串)
Level: Medium 题目描述: Given a string s, find the longest palindromic substring in s. You may assume ...
- 面试常用算法——Longest Palindromic Substring(最长回文子串)
第一种: public static void main(String[] args) { String s = "abcbaaaaabcdcba"; int n,m; Strin ...
- Manacher's algorithm: 最长回文子串算法
Manacher 算法是时间.空间复杂度都为 O(n) 的解决 Longest palindromic substring(最长回文子串)的算法.回文串是中心对称的串,比如 'abcba'.'abcc ...
- 最长回文子串-LeetCode 5 Longest Palindromic Substring
题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...
- [译+改]最长回文子串(Longest Palindromic Substring) Part II
[译+改]最长回文子串(Longest Palindromic Substring) Part II 原文链接在http://leetcode.com/2011/11/longest-palindro ...
- [译]最长回文子串(Longest Palindromic Substring) Part I
[译]最长回文子串(Longest Palindromic Substring) Part I 英文原文链接在(http://leetcode.com/2011/11/longest-palindro ...
- 求最长回文子串 - leetcode 5. Longest Palindromic Substring
写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...
- LeetCode:Longest Palindromic Substring 最长回文子串
题目链接 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...
- lintcode :Longest Palindromic Substring 最长回文子串
题目 最长回文子串 给出一个字符串(假设长度最长为1000),求出它的最长回文子串,你可以假定只有一个满足条件的最长回文串. 样例 给出字符串 "abcdzdcab",它的最长回文 ...
随机推荐
- T对象序列化后T对象中属性字段不见了?
序列化:JsonConvert.SerializeObject(T) 直接在类的上面添加[Table("表名")] 在类上添加属性[DataContract] 在属性上添加属性[D ...
- ajax获取跨域数据
1.效果图 2.源码 <%@ page contentType="text/html;charset=UTF-8" language="java" %&g ...
- Java集合(一)HashMap
HashMap 特点: HashMap的key和value都允许为空,无序的,且非线程安全的 数据结构: HashMap底层是一个数组,数组的每一项又都是链表,即数据和链表的结合体.当新建一个Hash ...
- Spring学习笔记之基础、IOC、DI(1)
0.0 Spring基本特性 Spring是一个开源框架:是基于Core来架构多层JavaEE系统 1.0 IOC 控制反转:把对象的创建过程交给spring容器来做. 1.1 application ...
- hdu 2489 dfs枚举组合情况+最小生成树
大家都说,搜索是算法的基础.今天最这题就有体会了.在n个顶点里选择m个顶点,求最小生成树.用到了深搜的回溯.所有情况都能枚举. #include<iostream> #include< ...
- map 和 for
一.map 函数封装. ; [,,,,,,,].map(function(elem){ sum += elem; }) console.log('sum='+sum); 二.平时用for的写法. ,, ...
- Spring 获取propertise文件中的值
Spring 获取propertise文件中的值 Spring 获取propertise的方式,除了之前的博文提到的使用@value的注解注入之外,还可以通过编码的方式获取,这里主要说的是要使用Emb ...
- SqlServer与MySql语法比较
1.复制表(包括表结构.表数据) SqlServer: Select * into user_copy from user MySql: CREATE TABLE user_copy LIKE use ...
- TRS矩阵分解
transform = TRS T就是transform的最后一列.关于R和S的分解,PBRT给了一个公式:M_(i+1) = (M_i + ((M_i)^T)^(-1))*0.5,直到M收敛.M初始 ...
- 面试官:为什么mysql不建议执行超过3表以上的多表关联查询?
概述 前段时间在跟其他公司DBA交流时谈到了mysql跟PG之间在多表关联查询上的一些区别,相比之下mysql只有一种表连接类型:嵌套循环连接(nested-loop),不支持排序-合并连接(sort ...