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

    1、暴力解法 时间O(n^3) 空间O(1)

    string longestPalindrome(string s) {
        int len = s.length();
        if (len < 2) {
            return s;
        }
        int maxn = 1;
        int idx = 0;
        for (int i = 1; i < len - 1; i++) {
            for (int j = i + 1; j < len; j++) {
                string tmp = s.substr(i, j - i + 1);
                string tmp2 = tmp;
                reverse(tmp.begin(), tmp.end());
                if (tmp == tmp2 && j - i + 1 > maxn) {
                    maxn = j - i + 1;
                    idx = i;
                }
            }
        }
        return s.substr(idx, maxn);
    }

    2、动态规划 时间O(n^2) 空间O(n^2)

    边界条件

    • 当子串长度为1时,dp[i][i] = true
    • 当子串长度为2时,dp[i][j] = s[i]==s[j]

    动态转移方程

    • dp[i][j] = dp[i+1][j-1] && s[i] == s[j]
    string longestPalindrome(string s) {
        int len = s.length();
        if (len < 2) {
            return s;
        }
        int maxn = 1;
        int idx = 0;
        vector<vector<int> > dp(len, vector<int>(len));
        for (int i = 0; i < len; i++) {
            dp[i][i] = 1;
        }
        for (int j = 1; j < len; j++) {
            for (int i = 0; i < j; i++) {
                if (s[i] != s[j]) {
                    dp[i][j] = 0;
                }
                else
                {
                    if (j - i + 1 < 4) 
                        dp[i][j] = 1;
                    else
                        dp[i][j] = dp[i + 1][j - 1];
                }
    
                if (dp[i][j] && j - i + 1 > maxn) {
                    maxn = j - i + 1;
                    idx = i;
                }
            }
        }
        return s.substr(idx, maxn);
    }

    3、中心扩展 时间O(n^2) 空间O(1)

    以下标 i 表示的字符为中心点向两端扩展,判断扩展后的字符是否为回文串

    • 回文子串长度为奇数,中心为 s[i]
    • 回文子串长度为偶数,中心为 s[i, i+1]
    string longestPalindrome(string s) {
        int len = s.length();
        if (len < 2) {
            return s;
        }
        int maxn = 1;
        int idx = 0;
        
        for (int i = 0; i < len - 1; i++) {
            int oddLen = computeLen(s, i, i);
            int evenLen = computeLen(s, i, i + 1);
            int tempLen = max(oddLen, evenLen);
            if (tempLen > maxn) {
                maxn = tempLen;
                idx = i - (tempLen - 1) / 2;
            }
        }
        return s.substr(idx, maxn);
    }
    
    int computeLen(string s, int l, int r) {
        int len = s.length();
        int i = l, j = r;
        while (i >= 0 && j < len) {
            if (s[i] == s[j]) {
                i--; j++;
            }
            else
            {
                break;
            }
        }
        return j - i - 1;
    }
  • 相关阅读:
    用SQL SERVER取分组数据第一条:查出每个班级的成绩第一名
    [转]spring beans.xml
    [转]为什么要使用框架
    MySQL 5.6 for Windows 解压缩版配置安装
    [转]hql 语法与详细解释
    [转]slf4j + log4j原理实现及源码分析
    [转]最详细的Log4j使用教程
    yii2 checkbox 的使用实例
    Magento Order 状态详解
    yii2 设置多个入口文件
  • 原文地址:https://www.cnblogs.com/cicinnus/p/13227577.html
Copyright © 2011-2022 走看看