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

    题目二、最长回文子串

    回文串是指aba、abba、cccbccc、aaaa这种左右对称的字符串。

    输入一个字符串Str,输出Str里最长回文子串的长度。

    Input

    输入Str(Str的长度 <= 1000)

    Output

    输出最长回文子串的长度L。

    输入示例

    daabaac

    abccbaabccbaaaaaaaaaaaaaaaaaaaaaaaaaaaa

    asdfghjkltlkjhgfdsaasdfghjkl

    qwertyuioppoiuytrewqqwertyuioplkjhgfdsazxcvbnmmnbvcxzasdfghjklpoiuytrewqssssssssddddddddd

    ddddddkkkkkkkkkkddddddddddddkkkkkkkkkkddddddddddddkkkkkkkkkkddddddddddddkkkkkkkkkkddddddddddddkkkkkkkkkkddddddddddddkkkkkkkkkkddddddddddddkkkkkkkkkkddddddddddddkkkkkkkkkkdddddd

    输出示例

    5

    28

    19

    52

    176

    解题思路:

    1.暴力法,先写一个判断是否是回文的函数,设置两个指针i和j,i从1到len,j从i+1到len,判断i到j是不是回文串。时间复杂度为平方级,下述的代码有bug,样例2和5通不过。

    代码:

     1 #include <cstdio>
     2 #include <cstring>
     3 #define MAXN 1010 //最大数组 
     4 int ans = 0; // 存放最大回文串的数组 
     5 bool judge(char str[], int left, int right) {
     6     int len = right - left;
     7     for (int i = 0; i < len; i++) {
     8         if (str[i] != str[len - i - 1]) { // 判断对称位置是否相等 
     9             return false;
    10         }
    11     }
    12     if (len > ans) ans = len;  //更新最长 
    13     return true;
    14 }
    15 
    16 int main() {
    17     int n = 5;
    18     while (n--) {
    19         char str[MAXN];
    20         scanf("%s", &str);
    21         int len = strlen(str);
    22         ans = 0;
    23         for (int i = 0; i < len - 1; i++) {
    24             for (int j = i + 1; j < len; j++) {
    25                 judge(&(str[i]), i, j);
    26             }
    27         }
    28         printf("%d
    ", ans);
    29     } 
    30     return 0;
    31 }

    方法2:动态规划

    不知道怎么解释了,直接上代码吧:

    #include <cstdio>
    #include <cstring>
    #define MAXN 1010
    char S[MAXN];
    int dp[MAXN][MAXN];
    int main() {
        int n = 5;
        while (n--) {
            gets(S);
            int len = strlen(S), ans = 1;
            memset(dp, 0, sizeof(dp));
            for (int i = 0; i < len; i++) {
                dp[i][i] = 1;
                if (i < len - 1) {
                    if (S[i] == S[i + 1]) {
                        dp[i][i + 1] = 1;
                        ans = 2;
                    }
                }
            }
        
            for (int L = 3; L <= len; L++) {
                for (int i = 0; i + L - 1 < len; i++) {
                    int j = i + L - 1;
                    if (S[i] == S[j] && dp[i + 1][j - 1] == 1) {
                        dp[i][j] = 1;
                        ans = L;
                    }
                }
            }
            printf("%d
    ", ans);
        }
        return 0;
    }

    其实这两个都不是最优的算法,在后续我还会讲述时间复杂度为O(nlogn)的hash字符算法和最优的O(n)Manacher算法

  • 相关阅读:
    学习java第20天
    学习java第19天
    学习java第18天
    学习java第17天
    学习java第16天
    java架构师学习路线-Web分布式开发框架概述
    java架构师学习路线-并发编程的概念
    java架构师学习路线-Java系统中的微服务框架
    java架构师学习路线-HashMap的知识点总结归纳
    java架构师学习路线-Java并发编程的五种状态和两种创建方式
  • 原文地址:https://www.cnblogs.com/MATLABlearning001/p/5397030.html
Copyright © 2011-2022 走看看