最长回文子串递归解
longest palindromic substring recursive solution
我知道使用自下而上的动态规划方法在 O(n^2) 中解决此问题的解决方案。我特别在寻找自上而下的 dp 方法。是否可以使用递归解决方案实现最长回文子串?
这是我尝试过的方法,但在某些情况下它失败了,但我觉得我几乎在正确的轨道上。
#include <iostream>
#include <string>
using namespace std;
string S;
int dp[55][55];
int solve(int x,int y,int val)
{
if(x>y)return val;
int &ret = dp[x][y];
if(ret!=0){ret = val + ret;return ret;}
//cout<<"x: "<<x<<" y: "<<y<<" val: "<<val<<endl;
if(S[x] == S[y])
ret = solve(x+1,y-1,val+2 - (x==y));
else
ret = max(solve(x+1,y,0),solve(x,y-1,0));
return ret;
}
int main()
{
cin >> S;
memset(dp,0,sizeof(dp));
int num = solve(0,S.size()-1,0);
cout<<num<<endl;
}
对于这种情况:
if(S[x] == S[y])
ret = solve(x+1,y-1,val+2 - (x==y));
应该是:
if(S[x] == S[y])
ret = max(solve(x + 1, y - 1, val + 2 - (x==y)), max(solve(x + 1, y, 0),solve(x, y - 1, 0)));
因为,如果不能创建从 x 到 y 的子字符串,则需要涵盖其他两种情况。
另一个错误:
if(ret!=0){ret = val + ret;return ret;}
在这种情况下,您应该 return ret + val
而不是修改 ret
。
主要问题是您将最终的 val
存储到 dp[x][y]
,但这是不正确的。
示例:
acabc ,对于 x = 1 和 y = 1,val = 3,所以 dp[1][1] = 3
,但实际上应该是 1.
修复:
int solve(int x,int y)
{
if(x>y)return 0;
int &ret = dp[x][y];
if(ret!=0){return ret;}
if(S[x] == S[y]){
ret = max(max(solve(x + 1, y),solve(x, y - 1)));
int val = solve(x + 1, y - 1);
if(val >= (y - 1) - (x + 1) + 1)
ret = 2 - (x == y) + val;
}else
ret = max(solve(x+1,y),solve(x,y-1));
return ret;
}
/*C++ program to print the largest palindromic string present int the given string
eg. "babad" contains "bab" and "aba" as two largest substring.
by occurance, "bab" comes first hence print "bab".
*/
#include<bits/stdc++.h>
using namespace std;
bool ispalindrome(string s)
{
int l = s.length()-1;
int r = 0;
while(l>r){
if(s[l]!=s[r])
return false;
l--;r++;
}
return true;
}
int main()
{
string str,str1,str3;
vector<string> str2;
cin>>str;
int len = str.length();
for(int i=0;i<len;i++)
{
for(int j=i;j<=len;j++)
{
str1 = "";
str1.append(str,i,j);
if(ispalindrome(str1)){
str2.push_back(str1);
}
}
}
int max = 0;
for(int i=0;i<str2.size();i++)
{
if(str2[i].length()>max){
max = str2[i].length();
str3 = str2[i];
}
}
cout<<"MAXIMUM LENGTH IS : "<<max<<"\nLARGEST PALINDROMIC STRING IS : "<<str3<<endl;
return 0;
}
在Javascript中使用递归的最长回文:
const longestPalindrome = str => {
if (str.length > 1){
let [palindrome1, palindrome2] = [str, str];
for (let i=0;i<Math.floor(str.length/2);i++) {
if(str[i]!==str[str.length-i-1]) {
palindrome1 = longestPalindrome(str.slice(0, str.length-1));
palindrome2 = longestPalindrome(str.slice(1, str.length));
break;
}
}
return palindrome2.length > palindrome1.length ? palindrome2 : palindrome1;
} else {
return str;
}
}
console.log(longestPalindrome("babababababababababababa"));
#include <iostream>
using namespace std;
int ans=0;
bool fn(string &s,int i,int j){
if(i==j)
return 1;
if((j-i)==1&&s[i]==s[j])
return 1;
else if((j-i)==1&&s[i]!=s[j])
return 0;
if(s[i]==s[j]){
if(fn(s,i+1,j-1)){
ans=max(ans,j-i+1);
return 1;
}
else{
return 0;
}
}
else{
fn(s,i,j-1);
fn(s,i+1,j);
return 0;
}
}
int main() {
string s;
cin>>s;
int last=s.length()-1;
fn(s,0,last);
cout<<ans<<endl;
return 0;
}
这里是 python 解决方案:
class Solution:
def longestPalindrome(self, s: str) -> str:
memo = {}
def isPalindrome(left,right):
state = (left, right)
if state in memo: return memo[state]
if left >= right:
memo[state] = True
return True
if s[left] != s[right]:
memo[state] = False
return False
memo[state] = isPalindrome(left+1, right-1)
return memo[state]
N = len(s)
result = ""
for i in range(N):
for j in range(i,N):
if (j-i+1) > len(result) and isPalindrome(i,j):
result = s[i:j+1]
return result
我知道使用自下而上的动态规划方法在 O(n^2) 中解决此问题的解决方案。我特别在寻找自上而下的 dp 方法。是否可以使用递归解决方案实现最长回文子串?
这是我尝试过的方法,但在某些情况下它失败了,但我觉得我几乎在正确的轨道上。
#include <iostream>
#include <string>
using namespace std;
string S;
int dp[55][55];
int solve(int x,int y,int val)
{
if(x>y)return val;
int &ret = dp[x][y];
if(ret!=0){ret = val + ret;return ret;}
//cout<<"x: "<<x<<" y: "<<y<<" val: "<<val<<endl;
if(S[x] == S[y])
ret = solve(x+1,y-1,val+2 - (x==y));
else
ret = max(solve(x+1,y,0),solve(x,y-1,0));
return ret;
}
int main()
{
cin >> S;
memset(dp,0,sizeof(dp));
int num = solve(0,S.size()-1,0);
cout<<num<<endl;
}
对于这种情况:
if(S[x] == S[y])
ret = solve(x+1,y-1,val+2 - (x==y));
应该是:
if(S[x] == S[y])
ret = max(solve(x + 1, y - 1, val + 2 - (x==y)), max(solve(x + 1, y, 0),solve(x, y - 1, 0)));
因为,如果不能创建从 x 到 y 的子字符串,则需要涵盖其他两种情况。
另一个错误:
if(ret!=0){ret = val + ret;return ret;}
在这种情况下,您应该 return ret + val
而不是修改 ret
。
主要问题是您将最终的 val
存储到 dp[x][y]
,但这是不正确的。
示例:
acabc ,对于 x = 1 和 y = 1,val = 3,所以 dp[1][1] = 3
,但实际上应该是 1.
修复:
int solve(int x,int y)
{
if(x>y)return 0;
int &ret = dp[x][y];
if(ret!=0){return ret;}
if(S[x] == S[y]){
ret = max(max(solve(x + 1, y),solve(x, y - 1)));
int val = solve(x + 1, y - 1);
if(val >= (y - 1) - (x + 1) + 1)
ret = 2 - (x == y) + val;
}else
ret = max(solve(x+1,y),solve(x,y-1));
return ret;
}
/*C++ program to print the largest palindromic string present int the given string
eg. "babad" contains "bab" and "aba" as two largest substring.
by occurance, "bab" comes first hence print "bab".
*/
#include<bits/stdc++.h>
using namespace std;
bool ispalindrome(string s)
{
int l = s.length()-1;
int r = 0;
while(l>r){
if(s[l]!=s[r])
return false;
l--;r++;
}
return true;
}
int main()
{
string str,str1,str3;
vector<string> str2;
cin>>str;
int len = str.length();
for(int i=0;i<len;i++)
{
for(int j=i;j<=len;j++)
{
str1 = "";
str1.append(str,i,j);
if(ispalindrome(str1)){
str2.push_back(str1);
}
}
}
int max = 0;
for(int i=0;i<str2.size();i++)
{
if(str2[i].length()>max){
max = str2[i].length();
str3 = str2[i];
}
}
cout<<"MAXIMUM LENGTH IS : "<<max<<"\nLARGEST PALINDROMIC STRING IS : "<<str3<<endl;
return 0;
}
在Javascript中使用递归的最长回文:
const longestPalindrome = str => {
if (str.length > 1){
let [palindrome1, palindrome2] = [str, str];
for (let i=0;i<Math.floor(str.length/2);i++) {
if(str[i]!==str[str.length-i-1]) {
palindrome1 = longestPalindrome(str.slice(0, str.length-1));
palindrome2 = longestPalindrome(str.slice(1, str.length));
break;
}
}
return palindrome2.length > palindrome1.length ? palindrome2 : palindrome1;
} else {
return str;
}
}
console.log(longestPalindrome("babababababababababababa"));
#include <iostream>
using namespace std;
int ans=0;
bool fn(string &s,int i,int j){
if(i==j)
return 1;
if((j-i)==1&&s[i]==s[j])
return 1;
else if((j-i)==1&&s[i]!=s[j])
return 0;
if(s[i]==s[j]){
if(fn(s,i+1,j-1)){
ans=max(ans,j-i+1);
return 1;
}
else{
return 0;
}
}
else{
fn(s,i,j-1);
fn(s,i+1,j);
return 0;
}
}
int main() {
string s;
cin>>s;
int last=s.length()-1;
fn(s,0,last);
cout<<ans<<endl;
return 0;
}
这里是 python 解决方案:
class Solution:
def longestPalindrome(self, s: str) -> str:
memo = {}
def isPalindrome(left,right):
state = (left, right)
if state in memo: return memo[state]
if left >= right:
memo[state] = True
return True
if s[left] != s[right]:
memo[state] = False
return False
memo[state] = isPalindrome(left+1, right-1)
return memo[state]
N = len(s)
result = ""
for i in range(N):
for j in range(i,N):
if (j-i+1) > len(result) and isPalindrome(i,j):
result = s[i:j+1]
return result