zoukankan      html  css  js  c++  java
  • 【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();
            }
        }
    }
    
    
    
    
    
    
    
    
  • 相关阅读:
    vue中$router和$route的区别
    移动端rem自适应
    如何用Mac自带的QuickTime Player录制视频并制作GIF动图
    vue页面刷新重定向
    JavaScript Functional Programming:声明式与命令式
    配置一个可以使用Vue的History模式的后端服务
    vue使用jsx语法开发
    vue多页面项目配置
    JavaScript的本来面貌之默认结构
    JavaScript的本来面貌之默认值
  • 原文地址:https://www.cnblogs.com/XDU-Lakers/p/13582757.html
Copyright © 2011-2022 走看看