字符串最长回文子串_最长回文子串

本文介绍了一种使用动态规划自顶向下的方法来解决寻找字符串中最长回文子串的问题。通过初始化布尔二维数组存储子字符串是否为回文,以及最大长度和子串本身,文章详细解释了算法步骤,并提供了C++实现代码。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

字符串最长回文子串

Problem statement:

问题陈述:

Given a string str, find the longest palindromic substring. A substring need to be consecutive such that for any xixj i<j must be valid in the parent string too. Like "incl" is a substring of "includehelp" while "iel" is not

给定字符串str ,找到最长回文子字符串。 子字符串必须是连续的,以便对于任何x i x j i <j在父字符串中也必须有效。 像“ incl”是“ includehelp”的子字符串,而“ iel”不是

Input:

输入:

The first line of input contains an integer T, denoting the no of test cases then T test cases follow. Each test case contains a tring str.

输入的第一行包含一个整数T ,表示测试用例的数量,然后是T个测试用例。 每个测试用例都包含一个tring str

Output:

输出:

For each test case output will be a string which is the longest palindromic substring could be formed from the string str. There can be many valid answers, all are correct.

对于每个测试用例,输出将是一个字符串,该字符串是可以从字符串str形成的最长回文子字符串。 可能有许多有效答案,所有答案都是正确的。

Constraints:

限制条件:

1 <= T <= 100
1 <= length of string str <= 300

Example:

例:

Input:
test case:2

First test case:
Input string:
"aaaa"

Output:
Longest palindromic substring is: "aaaa"

Second test case:
Input string:
"abcaba"

Output:
Total count of palindromic sub-sequence is: "aba"

Explanation:

说明:

Test case 1: Input: "aaaa"

测试案例1:输入:“ aaaa”

The valid palindromic substrings are shown below:

有效回文子串如下所示:

Marked cells are character taken in subsequence:

标记的单元格是子序列中的字符:

longest palindromic substring (1)
longest palindromic substring (2)

So the longest one is "aaaa"

所以最长的是“ aaaa”

For the second test case,

对于第二个测试用例,

The substrings can be,
"a"
"b"
"c"
"aba"

So the longest one is "aba"

Solution approach

解决方法

This can be solved by using DP top-down approach,

这可以通过使用DP自上而下的方法来解决,

  1. Initialize a Boolean 2D array dp[n][n] to store whether the substrings are palindrome or not.

    初始化布尔2D数组dp [n] [n],以存储子字符串是否为回文。

  2. Initialize max to store max length of substring and p to store the substring itself.

    初始化max来存储子字符串的最大长度,并初始化p来存储子字符串本身。

    Initially,

    原来,

    p is the first character as that's the smallest palindrome of length 1 and max = 1.

    p是第一个字符,因为它是长度为 1且max = 1的最小回文。

  3. Fill up the base case,

    填满基本情况

    Base case is that each single character is a palindrome itself. And for length of two, i.e, if adjacent characters are found to be equal then

    基本情况是,每个字符本身都是回文。 对于两个字符的长度,即如果发现相邻字符相等,则

    dp[i][i+1]=true, else if characters are different then dp[i][i+1]=false

    dp [i] [i + 1] = true ,否则如果字符不同则dp [i] [i + 1] = false

    To understand this lets think of a string like "acaa"

    要理解这一点,可以考虑一个字符串,例如“ acaa”

    Here

    这里

    dp[0][1]=false

    dp [0] [1] = false

    Whereas for

    鉴于

    dp[2][3] =true

    dp [2] [3] = true

    for i=0 to n
    	// for single length characters
    	dp[i][i]=true 
    	if(i==n-1)
    		break;        
    	if(s[i]==s[i+1])
    		dp[i][i+1]=true
    	else
    		dp[i][i+1]=false;
    end for
    
    
  4. Compute for higher lengths,

    计算更长的长度,

    for len=3 to n
    	for start=0 to n-len
    		int end=start+len-1;
    		// start and end is matching and rest of 
    		// substring is already palindrome
    		if(s[end]==s[start]   && dp[start+1][end-1])
    			dp[start][end]=true;
    			Update max=len;
    			Update p=s.substr(start,len);
    		else
    			dp[start][end]=false;
    		end if
    	end for
    end for
    
    
  5. Final result is stored in p;

    最终结果存储在p中

So for higher lengths, if starting and ending index is the same then we recur for the remaining characters since we have the sub-problem result stored so we computed that. That's why we just update max to len as we are checking for increasing length at each iteration.

因此,对于更大的长度,如果开始索引和结束索引相同,则将重复其余字符,因为我们已存储了子问题结果,因此我们对其进行了计算。 这就是为什么我们在每次迭代中检查长度增加时仅将max更新为len的原因。

For proper understanding, you can compute the table by hand for the string "abcaba" to understand how it's working.

为了正确理解,您可以手动计算字符串“ abcaba”的表以了解其工作方式。

C++ Implementation:

C ++实现:

#include <bits/stdc++.h>
using namespace std;

string longestPalindrome(string s)
{

    int n = s.length();
    
    if (n == 0)
        return "";
    if (n == 1)
        return s;
    
    bool dp[n][n];
    
    string p = string(1, s[0]);
    int max = 1;
    
    for (int i = 0; i < n; i++) {
        dp[i][i] = true;
        if (i < n - 1 && s[i] == s[i + 1]) {
            dp[i][i + 1] = true;
            if (2 > max) {
                p = s.substr(i, 2);
                max = 2;
            }
        }
        else if (i < n - 1) {
            dp[i][i + 1] = false;
        }
    }

    for (int len = 3; len <= n; len++) {
        for (int j = 0; j <= n - len; j++) {
            int end = j + len - 1;
            if (s[j] == s[end]) {

                dp[j][end] = dp[j + 1][end - 1];
                if (dp[j][end] && len > max) {
                    max = len;
                    p = s.substr(j, len);
                }
            }
            else
                dp[j][end] = false;
        }
    }
    return p;
}

int main()
{
    int t;
    
    cout << "Enter number of testcases\n";
    cin >> t;
    
    while (t--) {
        string str;
    
        cout << "Enter the string\n";
        cin >> str;
    
        cout << "Longest palindromic substring: " << longestPalindrome(str) << endl;
    }
    
    return 0;
}

Output:

输出:

Enter number of testcases
2
Enter the string
anccnakj
Longest palindromic substring: anccna
Enter the string
abcaba
Longest palindromic substring: aba


翻译自: https://www.includehelp.com/icp/longest-palindromic-substring.aspx

字符串最长回文子串

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值