LeetCode刷题笔记 5. 最长回文子串

LeetCode刷题笔记 5. 最长回文子串

  • 暴力法(看看就好)
  • 动态规划
  • 中心扩展法
  • Manacher 算法(不用掌握,面试的时候绝大多数情况下不会要求写这个算法,了解思想即可)

C++中substr函数的用法

暴力法(看看就好)

class Solution {

private:

    bool valid(string s, int left, int right) {
        // 验证子串 s[left, right] 是否为回文串
        while (left < right) {
            if (s[left] != s[right]) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }

public:


    string longestPalindrome(string s) {
        // 特判
        int size = s.size();
        if (size < 2) {
            return s;
        }

        int maxLen = 1;
        string res = s.substr(0, 1);

        // 枚举所有长度大于等于 2 的子串
        for (int i = 0; i < size - 1; i++) {
            for (int j = i + 1; j < size; j++) {
                if (j - i + 1 > maxLen && valid(s, i, j)) {  
                //最后只返回最早出现的最长回文字符串(>maLen才被记录)
                    maxLen = j - i + 1;
                    res = s.substr(i, maxLen);
                }
            }
        }
        return res;
    }
};

动态规划

LeetCode刷题笔记 5. 最长回文子串_第1张图片
LeetCode刷题笔记 5. 最长回文子串_第2张图片

class Solution {
public:
    string longestPalindrome(string s) {
        int len=s.length();
        if(len<2) return s;
        vector<vector<bool>> dp(len,vector<bool>(len));
        for(int i=0;i<len;i++)
            dp[i][i]=true;
        int maxLen=1;
        int start=0;
        for(int j=1;j<len;j++){
            for(int i=0;i<j;i++){
                if(s[i]==s[j]){
                    if(j-i<3) dp[i][j]=true;
                    else dp[i][j]=dp[i+1][j-1];
                }else dp[i][j]=false;
                if(dp[i][j]){
                    int curLen=j-i+1;
                    if(curLen>maxLen){
                        maxLen=curLen;
                        start=i;
                    }
                }
            }
        }
        return s.substr(start,maxLen);        
    }
};
执行用时 内存消耗
548 ms 19 MB

中心扩展法

class Solution {
public:
    string centerSpread(string s,int left,int right){
        int len=s.length();
        int i=left;
        int j=right;
        while(i>=0&&j<len){
            if(s[i]==s[j]){
                j++;
                i--;
            }else break;
        }
        return s.substr(i+1,j-i-1);
    }
    string longestPalindrome(string s) {
        int len=s.length();
        if(len<2) return s;
        int maxLen=1;
        string res=s.substr(0,1);
        for(int i=0;i<len-1;i++){
            string oddStr=centerSpread(s,i,i);
            string enenStr=centerSpread(s,i,i+1);
            string maxLenStr=oddStr.length()>enenStr.length()?oddStr:enenStr;
            if(maxLenStr.length()>maxLen){
                maxLen=maxLenStr.length();
                res=maxLenStr;
            }
        }
        return res;
    }
};
执行用时 内存消耗
104 ms 128 MB
class Solution {
public:
    string centerSpread(string& s,int left,int right){  //是的,只是把参数改为引用就可以有这么大的提升!
        int len=s.length();
        int i=left;
        int j=right;
        while(i>=0&&j<len){
            if(s[i]==s[j]){
                j++;
                i--;
            }else break;
        }
        return s.substr(i+1,j-i-1);
    }
    string longestPalindrome(string s) {
        int len=s.length();
        if(len<2) return s;
        int maxLen=1;
        string res=s.substr(0,1);
        for(int i=0;i<len-1;i++){
            string oddStr=centerSpread(s,i,i);
            string enenStr=centerSpread(s,i,i+1);
            string maxLenStr=oddStr.length()>enenStr.length()?oddStr:enenStr;
            if(maxLenStr.length()>maxLen){
                maxLen=maxLenStr.length();
                res=maxLenStr;
            }
        }
        return res;
    }
};
执行用时 内存消耗
64 ms 32.8 MB

Manacher 算法(不用掌握,面试的时候绝大多数情况下不会要求写这个算法,了解思想即可)

恐怖如斯,我就看下提升程度!

class Solution {

private:

    int centerSpread(string& s, int center) {
        int len = s.size();
        int i = center - 1;
        int j = center + 1;
        int step = 0;
        while (i >= 0 && j < len && s[i] == s[j]) {
            i--;
            j++;
            step++;
        }
        return step;
    }

public:


    string longestPalindrome(string s) {
        // 特判
        int size = s.size();
        if (size < 2) {
            return s;
        }

        // 得到预处理字符串
        string str = "#";
        for (int i = 0; i < s.size(); ++i) {
            str += s[i];
            str += "#";
        }
        int sSize = 2 * size + 1;
        int maxLen = 1;

        int start = 0;
        for (int i = 0; i < sSize; i++) {
            int curLen = centerSpread(str, i);
            if (curLen > maxLen) {
                maxLen = curLen;
                start = (i - maxLen) / 2;
            }
        }
        return s.substr(start, maxLen);
    }
};
执行用时 内存消耗
44 ms 9.3 MB

你可能感兴趣的:(Leetcode)