题解 | #进阶的回文串#

进阶的回文串

https://www.nowcoder.com/practice/7cdfbf53b13d4ae1acdeecd129e3b6e3

详细请看代码和图解::alt

import java.util.Scanner;
public class Main {
    public static void main(String[] args) {
    Scanner scanner = new Scanner(System.in);
    String s = scanner.next();
    int n = s.length();
    
    // 判断长度x到y 是否是回文 的布尔集合,x=y时表示单体,isisPalindrome[x][y]=false 表示x到y的长度的字符串不是回文
    boolean[][] isisPalindrome = new boolean[n][n];

    // 表示长度x到y 回文阶数 的集合, order[x][y]=0 表示x到y的长度 时阶数为0,即不是回文
    int[][] order = new int[n][n];

    // 结果集,即最后的输出【专门搞一个输出数组的原因是题目要求输出每个阶数的数量,要知道一个阶数k的回文同时也是阶数 1 到 k-1 阶数的回文】
    int[] result = new int[n + 1];

    // !!!下面是代码逻辑处理:
    // 特殊1,x到y的长度为1时所有单体都是1阶回文
    for (int x = 0; x < n; ++x) {
        int y = x;
        isisPalindrome[x][y] = true;
        order[x][y] = 1;
    }
    // 特殊2,判断x到y长度为2时是否是2阶回文【注意如果符合条件,它肯定也是一阶回文,这里先统计最高阶,后续再考虑分别输出阶数】
    for(int x = 0;x < n-1;++x){
        int y = x+1;
        if(s.charAt(x) == s.charAt(y)){
            isisPalindrome[x][y] = true;
            order[x][y]=2;
        }else{
            isisPalindrome[x][y] = false;
            order[x][y]=0;
        }
    }
    //由特殊1+特殊2来反推当x到y的长度 >= 3时的情况
    for(int len = 3;len <= n;len++){
        for(int x = 0; x + len <= n;++x){
            int y = len + x - 1;
            if(s.charAt(x) == s.charAt(y) && isisPalindrome[x+1][y-1]){
                int size = len / 2 ;
                int left = order[x][x + size - 1];
                int right = order[y - size + 1][y];
                // 这里进行min判断,就是因为会有特例,例如abcdcba,它属于1阶,不是2阶,它的左右部分是abc、cba并不是回文;这时因为前面设置不是回文的数字为 order[x][y]=0 的原因,Math.min(left,right) = 0,1 + 0 = 1,故abcdcba被判断为1阶
                int currentorder = 1 + Math.min(left,right);
                isisPalindrome[x][y] = true;
                order[x][y]=currentorder;
            }else{
                isisPalindrome[x][y] = false;
                order[x][y]=0;
            }
        }
    }

    // 得到所有情况下的最高阶数后,进行统计,例如aaaa即是3阶回文串,也是2和1阶回文
    int k;
    for (int i = 0; i < n; ++i ) {
        for (int j = i; j < n; ++j) {
            k = order[i][j];
            if (k > 0) {
                for (int z = k; z > 0; --z) {
                    result[z]++;
                }
            }
        }
    }
    // 输出最后结果
    for (k = 1; k <= n; ++k) {
        System.out.print(result[k] + " ");
    }
}

}

#打卡编程#
全部评论

相关推荐

评论
点赞
收藏
分享

创作者周榜

更多
牛客网
牛客网在线编程
牛客网题解
牛客企业服务