LeetCode Hot100【5. 最长回文子串】

5. 最长回文子串

自己做

思路1:暴力解,超时

cpp 复制代码
class Solution {
public:
    bool checkPalindrome(const string s) {
        int len = s.size();         //长度 
        int mid = len / 2;          //中轴

        if (len % 2 == 1) {        //子串长为奇数的情况
            for (int i = 0; i <= mid; i++) {
                if (s[mid - i] != s[mid + i])        //发现不对称,即表示这个子串不是回文串
                    return false;
            }
        }
        else {                       //子串长为偶数的情况
            for (int i = 0; i < mid; i++) {
                if (s[i] != s[len - 1 - i])        //发现不对称,即表示这个子串不是回文串
                    return false;
            }
        }

        return true;
    }

    string longestPalindrome(string s) {
        int len = s.size();     //字符串长度
        int max = 1;            //最大长【默认一个字符为回文串】
        string c;               //保存目前子串
        int begin = 0, end = 0; //最长子串的起始和结束位置

        for (int i = 0; i < len; i++) {             //子串起始
            c = s[i];                             //重置子串
            for (int j = i + 1; j < len; j++) {       //子串延伸
                c += s[j];                        //延伸子串
                if (c.size() <= max) {             //必然不可能是最长子串,跳过检测
                }
                else if (checkPalindrome(c) && c.size() > max) {      //更新最长子串【目前的i和j】
                    begin = i;
                    end = j;
                    max = j - i + 1;                    //更新最长长度
                }
            }
        }
        //目前已经找到了最长回文串
        c = "";                 //重置子串
        for (int i = begin; i <= end; i++) {
            c += s[i];
        }
        return c;

    }
};

思路2:

cpp 复制代码
class Solution {
public:
    bool checkPalindrome(const string s,int front,int len) {
        int mid = len / 2;          //中轴

        if (len % 2 == 1) {        //子串长为奇数的情况
            for (int i = 0; i <= mid; i++) {
                if (s[front + mid - i] != s[front + mid + i])        //发现不对称,即表示这个子串不是回文串
                    return false;
            }
        }
        else {                       //子串长为偶数的情况
            for (int i = 0; i < mid; i++) {
                if (s[front + i] != s[front + len - 1 - i])        //发现不对称,即表示这个子串不是回文串
                    return false;
            }
        }

        return true;
    }

    string longestPalindrome(string s) {
        int len = s.size();     //字符串长度
        string c = "";               //保存目前子串

        for (int c_len = len; c_len > 0; c_len--) {       //子串长度从len开始递减
            for (int front = 0; front + c_len <= len; front++) {             //子串
                if (s[front] == s[front + c_len - 1]) {                    //只有当首尾字符一致才检测是否回文串
                    if (checkPalindrome(s,front, c_len)) {        //检测是否回文串
                        //目前已经找到了最长回文串
                        for (int i = front; i <= front + c_len - 1; i++) {
                            c += s[i];
                        }
                        return c;
                    }
            }
        }
        }
       
        //找不到的情况
        c += s[0];
        return c;

    }
};

看题解【想不出最优解】

cpp 复制代码
class Solution {
    public:
        string longestPalindrome(string s) {
            int n = s.size();
            if (n < 2) {            //只有一个字符的边界情况
                return s;
            }

            int max = 1;        //最大回文串长
            int begin = 0;      //最长回文串起始

            vector<vector<bool>> dp(n, vector<bool>(n));      //初始化dp[n][n]标记数组

            for (int i = 0; i < n; i++)
                dp[i][i] = true;                       //所有的单个字符都是回文串

            for (int len = 2; len <= n; len++) {        //子串长度
                for (int i = 0; i < n; i++) {           //子串起始位置
                    int j = i + len - 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];    //本来是回文串现在还是回文串,本来不是回文串就不可能是回文串
                        }
                    }

                    if (dp[i][j] && j - i + 1 > max) {      //如果该段是回文串且长度超过了之前的最大长,更新
                        max = len;
                        begin = i;
                    }

                }
                
            }
            
            //此时得到了最大回文串的长度和起始位置
            return s.substr(begin, max);
        }
    };

今日总结

回去重新把算法书捡起来

相关推荐
Wendy144138 分钟前
【线性回归(最小二乘法MSE)】——机器学习
算法·机器学习·线性回归
拾光拾趣录40 分钟前
括号生成算法
前端·算法
渣呵2 小时前
求不重叠区间总和最大值
算法
浮生带你学Java2 小时前
2025Java面试题及答案整理( 2025年 7 月最新版,持续更新)
java·开发语言·数据库·面试·职场和发展
拾光拾趣录2 小时前
链表合并:双指针与递归
前端·javascript·算法
好易学·数据结构2 小时前
可视化图解算法56:岛屿数量
数据结构·算法·leetcode·力扣·回溯·牛客网
香蕉可乐荷包蛋3 小时前
AI算法之图像识别与分类
人工智能·学习·算法
chuxinweihui3 小时前
stack,queue,priority_queue的模拟实现及常用接口
算法
tomato093 小时前
河南萌新联赛2025第(一)场:河南工业大学(补题)
c++·算法