【LeetCode】214. 最短回文串

题目链接

214. 最短回文串

题目描述

给定一个字符串 s,你可以通过在字符串前面添加字符将其转换为回文串。找到并返回可以用这种方式转换的最短回文串。

示例 1:
输入: "aacecaaa"
输出: "aaacecaaa"

示例 2:
输入: "abcd"
输出: "dcbabcd"

解题思路

1.常规思路

找出字符串s中所有以s[0]为起点的回文字符串中最长的那一个回文字符串,那剩余的元素逆序拼接至开头即可。

2.KMP算法

参考题解

将原字符串翻转,并加在原串后。由于回文串翻转后不变,因此前缀的回文串就等于后缀的回文串(公共前后缀),即求next数组的值。

AC代码

1.常规思路

class Solution {
    public String shortestPalindrome(String s) {
        char[] cs = s.toCharArray();
        if (cs.length <= 1) {
            return s;
        }
        int index = 0;
        for (int i = 0; i <= (cs.length - 1) / 2; i++) {
            index = Math.max(index, palindrome(cs, i));
        }

        if (index == cs.length) {
            return s;
        }
        StringBuilder sb = new StringBuilder(s);
        return new StringBuilder(s.substring(index + 1, cs.length)).reverse().append(sb).toString();
    }

    private int palindrome(char[] cs, int i) {
        int res = 0;
        if (isPalindrome1(cs, i)) {
            res = 2 * i;
        }
        if (isPalindrome2(cs, i)) {
            res = 2 * i + 1;
        }
        return res;
    }

    // aba情况回文子串
    private boolean isPalindrome1(char[] cs, int i) {
        for (int j = 0; j < i; j++) {
            if (cs[j] != cs[2*i - j]) {
                return false;
            }
        }
        return true;
    }

    // abba情况回文子串
    private boolean isPalindrome2(char[] cs, int i) {
        if (i >= cs.length / 2) {
            return false;
        }
        for (int j = 0; j <= i; j++) {
            if (cs[j] != cs[2*i + 1 - j]) {
                return false;
            }
        }
        return true;
    }
}

2.KMP算法

class Solution {
    int get_next(String needle){
        //next的数组大小必须是pattern字符串长度+1,这样才能算出最长公共前后缀的长度
        int[] next = new int[needle.length()+1];
        next[0] = -1;
        next[1] = 0;
        int k = 0;
        int i = 2;
        while(i < next.length){
            if(needle.charAt(i-1) == needle.charAt(k)){
                k++;
                next[i] = k;
                i++;
            }else if(k == 0){
                next[i] = 0;
                i++;
            }else k = next[k];
        }
        return next[next.length-1];
    }

    public String shortestPalindrome(String s) {
        if(s.length()<2) return s;
        StringBuffer sb = new StringBuffer(s);
        StringBuffer temp = new StringBuffer();
        //之所以加一个“#”,是因为防止出现s == "aaaa"这种情况,如果没有"#",temp=“aaaaaaaa”,则返回值cnt=8,如果加上“#”,cnt的返回值为s.length()=4;
        temp.append(s).append("#").append(sb.reverse().toString());
        int cnt = get_next(temp.toString());
        if(cnt == s.length()) return s;
        else{
            String index = s.substring(cnt,s.length());
            System.out.println(index);
            StringBuffer rever = new StringBuffer(index);
            return rever.reverse().append(s).toString();
        }
    }
}







posted @ 2020-08-29 17:08  控球强迫症  阅读(266)  评论(0编辑  收藏  举报