leetcode-5.最长回文子串-MY

74 阅读1分钟

第一版

    public static void main(String[] args) {
        String s1 = "cbbd";
//        String s1 = "babad";
        int len = s1.length();
        int[] max = new int[2];
        boolean[][] dp = new boolean[len][len];
        for (int i = 0; i < len; i++) {
            dp[i][i]=true;
        }
        for (int j = 1; j < len; j++) {
            char c1 = s1.charAt(j);
            for (int i = 0; i<j; i++) {
                char c2 = s1.charAt(i);
                if (c1 != c2) {
                    dp[i][j] = false;
                } else {
                    if (j - i < 3) {
                        dp[i][j] = true;
                    } else {
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }

                if (dp[i][j] && j - i + 1 > (max[1] - max[0])) {
                    max[0] = i;
                    max[1] = j - i + 1;
                }
            }

        }
        System.out.println(Arrays.toString(max));
        System.out.println(s1.substring(max[0],max[1]));
    }

输出

String s1 = "cbbd";
[1, 2]
b
======
String s1 = "babad";
[0, 3]
bab

程序出错

第二版

    public static void main(String[] args) {
        String s1 = "cbbd";
//        String s1 = "babad";
//        String s1 = "ac";
        int len = s1.length();

        // 记录最大回文串
        int[] max = new int[2];

        // 创建dp二维数组,容量为字符串长度,这里表现为行i,列j。
        boolean[][] dp = new boolean[len][len];

        // dp数组上的对角线初始化,对角线为[0,0],[1,1]这种单个字符,必定为回文串
        for (int i = 0; i < len; i++) {
            dp[i][i]=true;
        }

        for (int j = 1; j < len; j++) {
            // c1可以在外层循环计算,避免内层循环计算的性能损失
            char c1 = s1.charAt(j);
            for (int i = 0; i<j; i++) {
                char c2 = s1.charAt(i);

                // 左右两个字符不相等必定不为回文串
                if (c1 != c2) {
                    dp[i][j] = false;
                } else {
                    // 回文串长度=j-i+1,c1==c2,长度为3必为回文串
                    if (j - i +1 <= 3) {
                        dp[i][j] = true;
                    } else {
                        // 状态转移
                        dp[i][j] = dp[i + 1][j - 1];
                    }
                }
                // 判断最大回文串,当前状态必须为true,也就是当前必定是回文串才行
                // j-i+1 表示的是当前回文串的长度,因为i是追着j跑的
                if (dp[i][j] && j - i + 1 > (max[1] - max[0])) {
                    max[0] = i;
                    max[1] = j + 1;
                }
            }

        }
        System.out.println(Arrays.toString(max));

        // 预防出现“ac”这种情况,返回空串。
        // 若没有回文串,这j=max[1]是等于数组初始值也就是0
        System.out.println(s1.substring(max[0],max[1]==0?1:max[1]));
    }
s1.substring(max[0],max[1]==0?1:max[1]);

三目运算符的作用是预防,出现“ac”这种情况,返回空串。

提交记录

Screenshot 2023-03-22 at 17-28-14 5. 最长回文子串 - 力扣(LeetCode).png

Screenshot 2023-03-22 at 17-28-28 5. 最长回文子串 - 力扣(LeetCode).png