【LeetCode】214. 最短迴文串
阿新 • • 發佈:2020-08-29
題目連結
214. 最短迴文串
題目描述
給定一個字串 s,你可以通過在字串前面新增字元將其轉換為迴文串。找到並返回可以用這種方式轉換的最短迴文串。
示例 1:
輸入: "aacecaaa"
輸出: "aaacecaaa"
示例 2:
輸入: "abcd"
輸出: "dcbabcd"
解題思路
1.常規思路
找出字串s中所有以s[0]為起點的迴文字串中最長的那一個迴文字串,那剩餘的元素逆序拼接至開頭即可。
2.KMP演算法
參考題解
將原字串翻轉,並加在原串後。由於迴文串翻轉後不變,因此字首的迴文串就等於字尾的迴文串(公共前後綴)
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 { public: int commpute_next(string pattern){ vector<int>next(pattern.size() + 1, 0);//next的陣列大小必須是pattern字串長度+1,這樣才能算出最長公共前後綴的 //長度 next[0] = -1; next[1] = 0; // A沒有前後綴 int i = 2; // i表示next陣列的索引 int k = 0; while (i < next.size()) { if (pattern[i - 1] == pattern[k]) { // pattern索引比next索引小1 next[i] = k + 1; k = next[i]; ++i; } else if (k == 0){ next[i] = 0; ++i; } else{ k = next[k]; } } return next[next.size() - 1]; } string shortestPalindrome(string s) { if(s == ""){ return ""; } string reverse = ""; for (int i = s.size() - 1; i >= 0; --i) { reverse += s[i]; } string pattern = s + '#' + reverse; int max_len = commpute_next(pattern);//max_len含義:最長公共前後綴的長度 return reverse.substr(0, reverse.size() - max_len) + s; } };