zoukankan      html  css  js  c++  java
  • 最长回文子串

    1、问题描述

    给定一个字符串 s,找到 s 中最长的回文子串。

    2、算法分析

    大多数问题都可以用暴力法解决。暴力法将选出所有子字符串可能的开始和结束位置,并检验它是不是回文。

    • 时间复杂度:O(n3),假设 n 是输入字符串的长度,则 (n * (n−1))/2​ 为此类子字符串(不包括字符本身是回文的一般解法)的总数。因为验证每个子字符串需要 O(n) 的时间,所以运行时间复杂度是 O(n3)。

    • 空间复杂度:O(1)。 

    为了改进暴力法,我们首先观察如何避免在验证回文时进行不必要的重复计算。考虑 "ababa" 这个示例。如果我们已经知道 "bab" 是回文,那么很明显,"ababa" 一定是回文,因为它的左首字母和右尾字母是相同的。

    我们给出 P(i,j) 的定义如下:

    如果子串 Si...Sj ​是回文子串   p(i, j) = true
    
    其他情况                   p(i, j) = false
    

    因此:

    P(i, j) = ( P(i+1, j-1) and Si​ == Sj​)
    

    基本示例如下:

    P(i, i) = true
    
    P(i, i+1) = (Si ​== Si+1​)
    

    这产生了一个直观的动态规划解法,我们首先初始化一字母和二字母的回文,然后找到所有三字母回文,并依此类推…

    3、复杂度分析

    • 时间复杂度:O(n2),这里给出我们的运行时间复杂度为 O(n2)。

    • 空间复杂度:O(n2),该方法使用 O(n2) 的空间来存储表。

    4、代码实现

    #include <stdio.h>
    #include <stdlib.h>
    #include <string.h>
    
    char * longestPalindrome(char* s)
    {
        if (s == NULL || strlen(s) < 1) {
            return "";
        }
        int n = (int)strlen(s);
        
        // 初始化二维数组
        int matrix[n][n];
        for (int i = 0; i < n; i++)
            for (int j = 0; j< n; j++)
                matrix[i][j] = 0;
        
        int left  = 0;
        int right = 0;
        
        // i 从倒数第二个开始,从右往左。标识子串的起始位置
        for (int i = n - 2; i >= 0; i--) {
            
            matrix[i][i] = 1;
            
            // j 从 i 的下一位开始,从左往右。标识子串的结束位置
            for (int j = i + 1; j < n; j++) {
                
                // ①、s[i] == s[j]     ②、小于或等于 3 个字符     ③、内缩一位是回文子串
                matrix[i][j] = (s[i] == s[j] && (j - i < 3 || matrix[i+1][j-1]));
                
                // 获得最长的子串位置
                if(matrix[i][j] && right - left < j - i) {
                    left  = i;
                    right = j;
                }
                
                for (int m = 0; m < n; m++) {
                    for (int k = 0; k < n; k++)
                        printf("%d   ", matrix[m][k]);
                    printf("
    
    ");
                }
            }
        }
        
        char* sub = (char *)malloc(sizeof(char) * (right - left + 1));
        int i = 0;
        for (; i < right - left + 1; i++) {
            sub[i] = s[left + i];  //strncpy(sub, s+left, right+1);
        }
        sub[i] = '';
        
        return sub;
    }
    
    int main()
    {
        printf("%s", longestPalindrome("aaabaaaa"));
        
        return 0;
    }
    

    关键代码:

    matrix[i][j] = (s[i] == s[j] && (j - i < 3 || matrix[i+1][j-1])); 以及 i 和 j 的取值方向

  • 相关阅读:
    各系统添加根证书
    Nginx浏览目录配置及美化
    django-图形验证码(django-simple-captcha)
    django-manage.py参数
    js — 对象
    js — 数组Array
    js — 字符串
    js — 基础知识
    css — 定位、背景图、水平垂直居中
    css — 权重、继承性、排版、float
  • 原文地址:https://www.cnblogs.com/dins/p/longest-text-substring.html
Copyright © 2011-2022 走看看