LeetCode | 5. 最长回文子串

题:力扣

5. 最长回文子串

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

如果字符串的反序与原始字符串相同,则该字符串称为回文字符串。

 

示例 1:

输入:s = "babad"
输出:"bab"
解释:"aba" 同样是符合题意的答案。
示例 2:

输入:s = "cbbd"
输出:"bb"
 

提示:

1 <= s.length <= 1000
s 仅由数字和英文字母组成
通过次数1,342,682提交次数3,587,244

我的原始思路:

暴力搜索,找出所有字符串,然后判断是否是回文,判断方法为前后比对相等个数。

两层for循环,遍历区间起始位置和终止位置,然后判断这个区间是不是回文。

时间复杂度:O(n^3)

class Solution:
    def longestPalindrome(self, s1: str) -> str:
       
        left = 0
        right = len(s1) - 1   # 0,30   31
        huiwen = " "
        maxhuiwen = " "
        maxlong = 0

        for left in range(0,len(s1)) :          #(0,31) [)
            for right in range(left+1,len(s1)+1):   # 1,0,1,2
                s = s1[left:right]   # 起点:个数
                sleft = 0
                sright = len(s) - 1
                size = len(s)
                
                if (size % 2 == 0):
                    numTrue = 0
                    numloop = size // 2
                    for sleft in range(0,numloop):
                        if(s[sleft] == s[sright]):
                            numTrue = numTrue + 1
                            sright = sright - 1
                    if (numTrue == numloop):
                        huiwen = s
                        if(size >= maxlong):
                            maxlong = size
                            maxhuiwen = huiwen
                
                else:
                    numTrue = 0
                    numloop = size // 2 + 1
                    for sleft in range(0,numloop):
                        if(s[sleft] == s[sright]):
                            numTrue = numTrue + 1
                            sright = sright - 1
                    if (numTrue == numloop):
                        huiwen = s
                        if(size >= maxlong):
                            maxlong = size
                            maxhuiwen = huiwen

        return maxhuiwen
class Solution {
public:
    string longestPalindrome(string s) {
        int left = 0;
        int right = s.size() - 1;
        string huiwen = " ";
        string maxhuiwen = " ";
        int maxlong = 0;

        for (left; left < s.size(); left++) {
            for (int k = 1; k < s.size() + 1; k++) {
                string str = s.substr(left, k);   //string s = "abcdbbfcba";  k是个数,不是位置
                int sright = str.size() - 1;
                int size = str.size();

                if (size % 2 == 0) {
                    int numTrue = 0;
                    for (int sleft = 0; sleft < size / 2; sleft++) {
                        char ssleft = str[sleft];
                        char ssright = str[sright];
                        if (ssleft == ssright) {
                            numTrue = numTrue + 1;
                            sright = sright - 1;
                        }
                        else {
                            sright = sright - 1;
                        }
                    }
                    if (numTrue == size / 2) {
                        huiwen = str;
                        if (size >= maxlong) {
                            maxlong = size;
                            maxhuiwen = huiwen;
                        }
                    }
                }
                else {
                    int numTrue = 0;
                    for (int sleft = 0; sleft < (size / 2 + 1); sleft++) {
                        char ssleft = str[sleft];
                        char ssright = str[sright];
                        if (ssleft == ssright) {
                            numTrue = numTrue + 1;
                            sright = sright - 1;
                        }
                        else {
                            sright = sright - 1;
                        }
                    }
                    if (numTrue == (size / 2 + 1)) {
                        huiwen = str;
                        if (size >= maxlong) {
                            maxlong = size;
                            maxhuiwen = huiwen;
                        }
                    }

                }
            }
        }
        return maxhuiwen;
    }
};

然而虽然能够求解出来,但是非常耗时,导致超出时间限制。

巧妙思路1:中心扩散法

  • 时间复杂度:O(n^2)

一排字符串按照位置循环

每个位置进行奇数偶数两种查找,即向外扩散。

class Solution {
public:
    string longestPalindrome(string s) { //string s = "aacabdkacaa";
        int len = 0;
        int maxlen = 0;
        string maxhuiwen = "";
        for (int i = 0; i < s.size(); i++) {
            int time = 0;
            int ttime = 0;
            int k = 0;
            int j = 0;
            int kk = 0;
            int jj = 0;
            //奇数
            for (j = i, k = i; j >=0 && k < s.size(); j--, k++) {     //奇数
                char left = s[j];
                char right = s[k];
                if (left == right) {
                    time = time + 1;
                }
                else {
                    break;
                }

            }
            len = time * 2 - 1 ;
            if (len >= maxlen) {
                maxlen = len;
                maxhuiwen = s.substr(i- time+1, len);
            }
            //偶数
            for (jj = i, kk = i+1; jj >= 0 && kk < s.size(); jj--, kk++) {     //偶数,bug:检查到不相等还继续找
                char ouleft = s[jj];
                char ouright = s[kk];
                if (ouleft == ouright) {
                    ttime = ttime + 1;
                }
                else {
                    break;
                }

            }
            len = ttime * 2 ;
            if (len >= maxlen) {
                maxlen = len;
                maxhuiwen = s.substr(i - ttime + 1, len);
            }
        }
        return maxhuiwen;
    }

};

整理得:

class Solution {
public:
    string longestPalindrome(string s) {
        for (int i = 0; i < s.size(); i++) {
            func(s, i, i); // 奇数长度的子串
            func(s, i, i + 1); // 偶数长度的子串
        }
        return s.substr(start, len);
    }
private:
    // 用于构造最长子串
    int start;
    int len = 0;

    void func(string& s, int i, int j) {
        while (i >= 0 && j < s.size() && s[i] == s[j]) {
            if (j - i + 1 > len) {
                // 定位暂时最长的子串位置
                start = i;
                len = j - i + 1;
            }
            i--;
            j++;
        }

    }
};

——————

浅谈则止,细致入微AI大道理

扫描下方“AI大道理”,选择“关注”公众号

—————————————————————

—————————————————————

猜你喜欢

转载自blog.csdn.net/qq_42734492/article/details/129378440