动态规划之最长回文子字符串(Longest Palindromic Substring)

原文地址:Longest Palindromic Substring | Set 1

已知一个字符串。找出这个字符串中的最长回文子字符串。例如,如果已知的字符串是:“forgeeksskeegfor”,那么输出的结果应该是:“geeksskeeg”。

方法1 (暴力法)
最简单的方法就是检验每一个子字符串,看看它们到底是不是回文的。我们可以用三层循环,外面的两个循环根据固定的边角字符逐个找出所有的子字符串,最内部的循环则是检验这个子字符串是不是回文的。

时间复杂度:O ( n^3 )
空间复杂度:O ( 1 )

方法 2 (动态规划)
这个问题可以通过存子问题的结果来降低时间复杂度。我们将维护一个boolean类型的数组table[n][n],这个数组是自底向上填充的。如果子字符串是惠乃文的,那么table[i][j]就是true。为了计算table[i][j],我们首先要检查table[i+1][j-1]的值,如果这个值是true,并且str[i]与str[j]相同,那么table[i][j]就是true。否则,table[i][j]的值是false。

// A dynamic programming solution for longest palindr.
// This code is adopted from following link
// http://www.leetcode.com/2011/11/longest-palindromic-substring-part-i.html

#include <stdio.h>
#include <string.h>

// A utility function to print a substring str[low..high]
void printSubStr( char* str, int low, int high )
{
    for(int i = low; i <= high; ++i)
        printf("%c", str[i]);
}

// This function prints the longest palindrome substring
// of str[].
// It also returns the length of the longest palindrome
int longestPalSubstr(char *str)
{
    int n = strlen( str ); // get length of input string

    // table[i][j] will be false if substring str[i..j]
    // is not palindrome.
    // Else table[i][j] will be true
    bool table[n][n];
    memset(table, 0, sizeof(table));

    // All substrings of length 1 are palindromes
    int maxLength = 1;
    for (int i = 0; i < n; ++i)
        table[i][i] = true;

    // check for sub-string of length 2.
    int start = 0;
    for (int i = 0; i < n-1; ++i)
    {
        if (str[i] == str[i+1])
        {
            table[i][i+1] = true;
            start = i;
            maxLength = 2;
        }
    }

    // Check for lengths greater than 2. k is length
    // of substring
    for (int k = 3; k <= n; ++k)
    {
        // Fix the starting index
        for (int i = 0; i < n-k+1 ; ++i)
        {
            // Get the ending index of substring from
            // starting index i and length k
            int j = i + k - 1;

            // checking for sub-string from ith index to
            // jth index iff str[i+1] to str[j-1] is a
            // palindrome
            if (table[i+1][j-1] && str[i] == str[j])
            {
                table[i][j] = true;

                if (k > maxLength)
                {
                    start = i;
                    maxLength = k;
                }
            }
        }
    }

    printf("Longest palindrome substring is: ");
    printSubStr(str, start, start + maxLength - 1);

    return maxLength; // return length of LPS
}

// Driver program to test above functions
int main()
{
    char str[] = "forgeeksskeegfor";
    printf("\nLength is: %d\n", longestPalSubstr(str));
    return 0;
}

输出:

Longest palindrome substring is: geeksskeeg
Length is: 10

时间复杂度:O ( n^2 )
空间复杂度:O ( n^2 )

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值