LeetCode——5. 最长回文子串

题目描述

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

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

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

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

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

题解思路

答案不唯一的最长回文数,第一眼看到我觉得暴力解法和双指针方法都可以做,但是通不通过就不好说了,感觉会超过时间限制

我们直接来学习一下官方给出的动态规划思路吧,真的是惊得我目瞪口呆,借用二维数组来实现动态规划

核心思想是如果一个字符串两端的字符是相等的,那么就继续往中间判断,这样就可以把小问题的结果当成大问题的解

我们定义好要判断的字符串长度,然后从长度为1开始依次用二维数组来保存短的字符串是否为回文数

这样根据字符串长度越来越长,长度越长久就拿来代替ans返回,直到遍历完最长的字符串

这里有几个特殊情况,两端的时候不会是回文数,只有一个字符的时候也不会是,这样很多子串就可以直接赋值

正确代码

class Solution {
    public String longestPalindrome(String s) {
        int len = s.length();
        boolean[][] dp = new boolean[len][len];
        String ans = "";

        for (int l = 0; l < len; ++l) {
            for (int i = 0; i + l < len; ++i) {
                int j = i + l;
                if (l == 0) {
                    dp[i][j] = true;
                } else if (l == 1) {
                    dp[i][j] = (s.charAt(i) == s.charAt(j));
                } else {
                    dp[i][j] = (s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1]);
                }
                if (dp[i][j] && l + 1 > ans.length()){
                    ans = s.substring(i,i+l+1);
                }
            }
        }
        return ans;
    }
}

总结

说实话再让我遇到这道题我估计还得懵,但是动态规划的核心思想就是找到转换公式

让大问题的解运用子问题的解,用空间来换取时间,其实用动态规划方法的效率也不是很高

暴力解法的复杂度为O(n^3),动态规划的复杂度为O(n^2),官方还有一种 Manacher 算法复杂度达到了线性

不过囫囵吞枣终究是不好的,以后等自己技术再增长之后再来挑战吧,当然多学一种思想肯定是不赖的

如果文章存在什么问题或者有更好的题解,欢迎评论区斧正和评论,各自努力,你我最高处见
posted @ 2021-04-06 09:54  21岁还不是架构师  阅读(54)  评论(0编辑  收藏  举报