首页 > 其他分享 >LeetCode最长回文子串(/dp)

LeetCode最长回文子串(/dp)

时间:2023-01-22 19:00:29浏览次数:46  
标签:right int len LeetCode start arm dp 回文

原题解

题目

约束

解法

解法一

#include <iostream>
#include <string>
#include <vector>

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);
    }
};

解法二

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);
    }
};

解法三

class Solution {
public:
    int expand(const string& s, int left, int right) {
        while (left >= 0 && right < s.size() && s[left] == s[right]) {
            --left;
            ++right;
        }
        return (right - left - 2) / 2;
    }

    string longestPalindrome(string s) {
        int start = 0, end = -1;
        string t = "#";
        for (char c: s) {
            t += c;
            t += '#';
        }
        t += '#';
        s = t;

        vector<int> arm_len;
        int right = -1, j = -1;
        for (int i = 0; i < s.size(); ++i) {
            int cur_arm_len;
            if (right >= i) {
                int i_sym = j * 2 - i;
                int min_arm_len = min(arm_len[i_sym], right - i);
                cur_arm_len = expand(s, i - min_arm_len, i + min_arm_len);
            } else {
                cur_arm_len = expand(s, i, i);
            }
            arm_len.push_back(cur_arm_len);
            if (i + cur_arm_len > right) {
                j = i;
                right = i + cur_arm_len;
            }
            if (cur_arm_len * 2 + 1 > end - start) {
                start = i - cur_arm_len;
                end = i + cur_arm_len;
            }
        }

        string ans;
        for (int i = start; i <= end; ++i) {
            if (s[i] != '#') {
                ans += s[i];
            }
        }
        return ans;
    }
};

标签:right,int,len,LeetCode,start,arm,dp,回文
From: https://www.cnblogs.com/chuixulvcao/p/17064569.html

相关文章

  • LeetCode_单周赛_329
    2544.交替数字和代码1转成字符串,逐个判断classSolution{publicintalternateDigitSum(intn){char[]s=(""+n).toCharArray();intt......
  • 【队列】LeetCode 281. 锯齿迭代器
    题目链接281.锯齿迭代器思路使用队列进行保存代码publicclassZigzagIterator{Queue<Iterator<Integer>>queue=newLinkedList<>();publicZigzagIt......
  • 【队列】LeetCode 346. 数据流中的移动平均值
    题目链接346.数据流中的移动平均值思路队列设计基础题代码classMovingAverage{privateIntegercurrentSum=0;privateQueue<Integer>queue=newLi......
  • 网络分层 & http & tcp or udp
    ......
  • [LeetCode] 684. Redundant Connection
    Inthisproblem,atreeisan undirectedgraph thatisconnectedandhasnocycles.Youaregivenagraphthatstartedasatreewith n nodeslabeledfrom......
  • leetcode笔记——328周赛
    1.二维前缀和,二维差分304.二维区域和检索-矩阵不可变-力扣(LeetCode)二维前缀和怎么处理,注意加减的下标 2.2537.统计好子数组的数目-力扣(LeetCode)首先看到子数......
  • 【双指针】LeetCode 409. 最长回文串
    题目链接409.最长回文串思路遍历字符串过程中统计字符出现个数,如果达到2则说明可以放到回文串的两端,需要result+=2。遍历完之后的回文串如果长度小于s,说明s中存......
  • LeetCode.541 反转字符串II
    1.题目给定一个字符串s和一个整数k,从字符串开头算起,每计数至2k个字符,就反转这2k字符中的前k个字符。如果剩余字符少于k个,则将剩余字符全部反转。如果剩余字符小......
  • LeetCode.面试题02.05-链表求和-题解分析
    题目来源面试题02.05.链表求和题目详情给定两个用链表表示的整数,每个节点包含一个数位。这些数位是反向存放的,也就是个位排在链表首部。编写函数对这两个整数求和,并......
  • [LeetCode] 1824. Minimum Sideway Jumps
    Thereisa 3laneroad oflength n thatconsistsof n+1 points labeledfrom 0 to n.Afrog starts atpoint 0 inthe second lane andwantsto......