最长的回文子串递归解

时间:2015-04-30 04:26:45

标签: c++ algorithm recursion dynamic-programming palindrome

我知道使用自下而上动态编程方法在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;
}

4 个答案:

答案 0 :(得分:6)

对于这种情况:

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;
}

答案 1 :(得分:0)

/*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;
}

答案 2 :(得分: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"));

答案 3 :(得分:-1)

#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;
}