• 刷题-最长回文子串-C++解法


    一、题目描述

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

    二、几种思路

    1.动态规划思想解决

    2.中心扩展算法(所有状态在转移的时候可能性都是唯一的)

    3.暴力法(可能会超出时间限制)

    三、一些解法

    1.动态规划思想(C++解决)

    #include 
    #include 
    #include 
    
    using namespace std;
    
    class Solution {
    public:
        string longestPalindrome(string s) {
            int n = s.size();
            if (n < 2) {
                return s;
            }
    
            int maxLen = 1;
            int begin = 0;
            // dp[i][j] 表示 s[i..j] 是否是回文串
            vector<vector<int>> dp(n, vector<int>(n));
            // 初始化:所有长度为 1 的子串都是回文串
            for (int i = 0; i < n; i++) {
                dp[i][i] = true;
            }
            // 递推开始
            // 先枚举子串长度
            for (int L = 2; L <= n; L++) {
                // 枚举左边界,左边界的上限设置可以宽松一些
                for (int i = 0; i < n; i++) {
                    // 由 L 和 i 可以确定右边界,即 j - i + 1 = L 得
                    int j = L + i - 1;
                    // 如果右边界越界,就可以退出当前循环
                    if (j >= n) {
                        break;
                    }
    
                    if (s[i] != s[j]) {
                        dp[i][j] = false;
                    } else {
                        if (j - i < 3) {
                            dp[i][j] = true;
                        } else {
                            dp[i][j] = dp[i + 1][j - 1];
                        }
                    }
    
                    // 只要 dp[i][L] == true 成立,就表示子串 s[i..L] 是回文,此时记录回文长度和起始位置
                    if (dp[i][j] && j - i + 1 > maxLen) {
                        maxLen = j - i + 1;
                        begin = i;
                    }
                }
            }
            return s.substr(begin, maxLen);
        }
    };
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35
    • 36
    • 37
    • 38
    • 39
    • 40
    • 41
    • 42
    • 43
    • 44
    • 45
    • 46
    • 47
    • 48
    • 49
    • 50
    • 51
    • 52
    • 53
    • 54

    2.中心扩展算法解决

    class Solution {
    public:
        pair<int, int> expandAroundCenter(const string& s, int left, int right) {
            while (left >= 0 && right < s.size() && s[left] == s[right]) {
                --left;
                ++right;
            }
            return {left + 1, right - 1};
        }
    
        string longestPalindrome(string s) {
            int start = 0, end = 0;
            for (int i = 0; i < s.size(); ++i) {
                auto [left1, right1] = expandAroundCenter(s, i, i);
                auto [left2, right2] = expandAroundCenter(s, i, i + 1);
                if (right1 - left1 > end - start) {
                    start = left1;
                    end = right1;
                }
                if (right2 - left2 > end - start) {
                    start = left2;
                    end = right2;
                }
            }
            return s.substr(start, end - start + 1);
        }
    };
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29

    3,暴力法解决

    class Solution {
    public:
        string longestPalindrome(string s) {
            string res="";//存放结果
            string temp="";//存放子串
            for(int i=0;i<s.length();i++)
            {
                for(int j=i;j<s.length();j++)
                {
                    temp=temp+s[j];
                    string tem=temp;//tem存放子串反转结果
                    std::reverse(tem.begin(),tem.end());//反转
                    if(temp==tem)
                        res=res.length()>temp.length()?res:temp;
                }
                temp="";
            }
            return res;
        }
    };
    
    
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22

    四、对比总结

    1动态规划思想的复杂度
    时间复杂度:O(n^2)
    其中 nn 是字符串的长度。
    空间复杂度:O(n^2)
    即存储动态规划状态需要的空间。

    2.中心扩展算法复杂度
    时间复杂度:O(n^2)
    其中 nn是字符串的长度。
    空间复杂度:O(1)

  • 相关阅读:
    MVCC究竟是什么?
    LeetCode每日一练 —— 88. 合并两个有序数组
    北京化工大学数据结构2022/11/3作业 题解
    【微信小程序开发】宠物预约医疗项目实战-开发功能介绍
    SwiftUI 动态岛开发教程之02 iPhone 14 Pro 如何使用 Dynamic Island
    python语法之变量名
    PDA 红外扫码 uniapp
    Guitar Pro8许可证序列号是多少?
    案例:MySQL主从复制与读写分离
    Android app 通过meta-data向setting里添加菜单
  • 原文地址:https://blog.csdn.net/weixin_45594172/article/details/126865220