【LeetCode笔记】5.最长回文子串(Java、动态规划、字符串)

文章目录

  • 题目描述
  • 解法 & 代码:
      • 思路

题目描述

  • 回文:正着念和倒着念一样。
    【LeetCode笔记】5.最长回文子串(Java、动态规划、字符串)_第1张图片

解法 & 代码:

  • 一开始看到子串,想着可能no.3最长重复子串一样用滑动窗口。不过回文串的判断会很麻烦,于是舍弃。
  • 之后看题解,用的是动态规划。

思路

  • 从短串,到长串循环,最终得到一个dp[][]二维矩阵,dp[i][j]代表S(i,j)是否是回文串。
  • 单个元素的情况,必然是回文串。dp[i][i]。
  • 两个元素的情况,根据S[i] == S[i+1]即可判断。
  • 多个元素的情况,根据dp[i+1][j-1]以及S[i] == S[j]即可判断。
  • 有了这三种情况,我们就有了状态转移方程。
  • 对于循环,可以看成是对于每一个子串长度,都从每一个左边界 i开始构成串:因此j > i的情况全算是false
class Solution {
    public String longestPalindrome(String s) {
        // 用dp(Dynamic Programming)
        int len = s.length();
        // 空间复杂度O(n*n)
        boolean[][] dp = new boolean[len][len];
        String ans = "";

        // 字串长度nowLen
        for (int nowLen = 0; nowLen < len; nowLen++) {
            // 字串左边界i
            for (int i = 0; i + nowLen < len; i++) {
                // 字串右边界
                int j = i + nowLen;
                // 子串单个元素的情况
                if (nowLen == 0) {
                    dp[i][j] = true;
                }
                // 子串两个元素的情况
                else if (nowLen == 1) {
                    dp[i][j] = (s.charAt(i) == s.charAt(j));
                }
                // 多个元素的情况:用之前的结果构造当前结果
                else {
                    dp[i][j] = dp[i + 1][j - 1] && (s.charAt(i) == s.charAt(j));
                }
                if (ans.length() < j - i + 1 && dp[i][j]) {
                    ans = s.substring(i, j + 1);
                }
            }
        }
        return ans;
    }
}
  • 时间复杂度:O( n 2 n^2 n2):因为动态规划的状态总数为 n 2 n^2 n2,对于每一个状态进行转移的时间为O(1)
  • 空间复杂度:O( n 2 n^2 n2):也就是dp[n][n],存储动态规划状态需要的空间。

你可能感兴趣的:(LeetCode要每天都刷噢,动态规划,leetcode,java,算法,字符串)