• 算法-动态规划/中心扩散法-最长回文子串


    算法-动态规划/中心扩散法-最长回文子串

    1 题目概述

    1.1 题目出处

    https://leetcode.cn/problems/longest-palindromic-substring

    1.2 题目描述

    在这里插入图片描述

    2 动态规划

    2.1 思路

    dp[i][j] 表示[i,j]之间的字符串是否是回文。
    那么,如果chars[i] = chars[j]时,就有可能构成的子串为回文:

    1. 如果j - i < 3,则子串肯定是回文。比如 aba、aa、a
    2. 如果j - i >=3,则就会用到动态规划了,即 dp[i][j] = dp[i+1][j-1],也就是说 i的下一个字符和j的前一个字符组成的闭区间子串是否是回文,只要是那么本子序列也是。
    3. 这里有个重要的点,表达式为dp[i][j] = dp[i+1][j-1],也就是说i取决于i+1,j取决于j-1,所以遍历时需要i从大到小计算,而j需要从小到大计算。
    4. 遍历过程中,每当判断子序列为回文,就和之前已经找到的最大回文长度的比较,如果更长就更新,并记录下i、j
    5. 最后将字符串从i、j取子序列即可

    2.2 代码

    public class Solution {
    
        public String longestPalindrome(String s) {
            // 表示[i,j]之间的字符串是否是回文
            boolean[][] dp = new boolean[s.length()][s.length()];
            for(int i = 0; i < s.length(); i++) {
                // 定义同一个位置的为true
                dp[i][i] = true;
            }
    
            int maxLength = 0;
            int left = 0, right = 0;
    
            for (int i = s.length() - 1; i >= 0; i--) {
                for (int j = i + 1; j < s.length(); j++) {
                    if (s.charAt(i) == s.charAt(j)) {
                        if (j - i < 3) {
                            dp[i][j] = true;
                        } else {
                            dp[i][j] = dp[i+1][j-1];
                        }
                        if (dp[i][j] && (j - i + 1 > maxLength)) {
                            maxLength = j - i + 1;
                            left = i;
                            right = j;
                        }
                    }
                }
            }
            
            return s.substring(left, right+1);
        }
    
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34

    2.3 时间复杂度

    O(N^2)
    在这里插入图片描述

    2.4 空间复杂度

    O(N^2)

    3 中心扩散

    3.1 思路

    从左到右移动,每当移动一次后,往两边扩散,直到两侧边界字符不符合回文规则。

    3.2 代码

    public class Solution {
        int maxLength = 0;
        int left = 0, right = 0;
    
        public String longestPalindrome(String s) {
            for (int i = 0; i < s.length() - 1; i++) {
                // 字符串奇数长度时,中间一个字符串往两边扩散
               spread(i, i, s);
               // 字符串偶数长度时,中间两个字符串往两边扩散
               spread(i, i+1, s);
            }
            
            return s.substring(left, right+1);
        }
    
        private void spread(int i, int j, String s) {
            while (i >= 0 && j < s.length()) {
                if (s.charAt(i) != s.charAt(j)) {
                    break;
                } 
                i--;
                j++;
            }
    
            // 把多减了、加了的补上
            i++;
            j--;
    
            if (j - i + 1 > maxLength) {
                left = i;
                right = j;
                maxLength = j - i + 1;
            }
        }
    }
    
    • 1
    • 2
    • 3
    • 4
    • 5
    • 6
    • 7
    • 8
    • 9
    • 10
    • 11
    • 12
    • 13
    • 14
    • 15
    • 16
    • 17
    • 18
    • 19
    • 20
    • 21
    • 22
    • 23
    • 24
    • 25
    • 26
    • 27
    • 28
    • 29
    • 30
    • 31
    • 32
    • 33
    • 34
    • 35

    3.3 时间复杂度

    在这里插入图片描述
    O(N^2)

    3.4 空间复杂度

    O(1)

    参考文档

  • 相关阅读:
    单播与多播mac地址
    动态规划经典入门
    Java面试题--RocketMQ
    宏鑫科技在创业板过会:前三季度收入约7亿元,王文志为实控人
    购买altium服务器许可证价格的疑问
    Bankless:Maker DAO的生存危机
    2022 uuctf--- crypto Impossible_RSA
    【数据结构】链表与LinkedList
    思科交换机65系列配置
    【cocos2dx】学习记录,Node的自动释放(autorelease)
  • 原文地址:https://blog.csdn.net/baichoufei90/article/details/133718572