5. 最长回文子串[中等]

103 阅读1分钟

问题

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

示例 1:

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

输入:s = "cbbd" 输出:"bb" 示例 3:

输入:s = "a" 输出:"a" 示例 4:

输入:s = "ac" 输出:"a"

提示: 1 <= s.length <= 1000 s 仅由数字和英文字母(大写和/或小写)组成

思路一

暴力解法。可以遍历所有的子串,找出最长的。

代码一

class Solution {
    public String longestPalindrome(String s) {
        int maxLen = 1;
        int start = 0;
        // charAt每次都要检测是否越界
        char[] chars = s.toCharArray();
        int length = s.length();
        for (int i = 0; i < length; i++) {
            for (int j = i + 1; j < length; j++) {
                if ((j - i + 1) > maxLen && isPalindrome(chars, i, j)) {
                    maxLen = j - i + 1;
                    start = i;
                }
            }
        }
        return s.substring(start, start + maxLen);
    }
    private boolean isPalindrome(char[] chars, int i, int j) {
        while (i < j) {
            if (chars[i] != chars[j]) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    }
}

复杂度一

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

空间复杂度:O(n)

思路二

可以使用动态规划解决。定义d[i][j]表示字符串从i开始到j结束是否是回文子串。对于d[i][j],如果d[i+1][j-1]是回文串而且s[i] == s[j],则d[i][j]也是回文串。

代码二

class Solution {
    public String longestPalindrome(String s) {
        int length = s.length();
        char[] chars = s.toCharArray();
        boolean[][] d = new boolean[length][length];
        int max = 1;
        int start = 0;
        // len表示可能回文子串的长度
        for (int len = 1; len <= length; len++) {
            // i + len -1表示长度为len的可能回文子串最后一个字符
            for (int i = 0; i + len - 1 < length; i++) {
                int j = i + len - 1;
                if (len == 1) {
                    d[i][j] = true;
                } else if (len == 2) {
                    d[i][j] = (chars[i] == chars[j]);
                } else {
                    d[i][j] = (chars[i] == chars[j] && d[i+1][j-1]);
                }
                if (d[i][j] && len > max) {
                    max = len;
                    start = i;
                }
            }
        }
        return s.substring(start, start + max);
    }
}

复杂度二

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

空间复杂度:O(n^2)

update 20220503

    public String longestPalindrome(String s) {
        int length = s.length();
        int max = 0;
        int start = 0;
        int end = 0;
        for (int i = 0; i < length; i++) {
            for (int j = length - 1; j > i; j--) {
                int len = j - i + 1;
                if (len > max && isPalindrome(s, i, j)) {
                        max = len;
                        start = i;
                        end = j;
                }
            }
        }
        return s.substring(start, end + 1);
    }

    private boolean isPalindrome(String s, int start, int end) {
        int i = start;
        int j = end;
        while (i < j) {
            char left = s.charAt(i);
            char right = s.charAt(j);
            if (left != right) {
                return false;
            }
            i++;
            j--;
        }
        return true;
    } 

硬广告

欢迎关注公众号:double6

final

本文正在参与「掘金 2021 春招闯关活动」, 点击查看 活动详情