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

来源:互联网 发布:学摄影的书籍知乎 编辑:程序博客网 时间:2024/06/06 08:28

原文地址: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 palindromeint 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 functionsint main(){    char str[] = "forgeeksskeegfor";    printf("\nLength is: %d\n", longestPalSubstr(str));    return 0;}

输出:

Longest palindrome substring is: geeksskeegLength is: 10

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

0 0