5. Longest Palindromic Substring && 214. Shortest Palindrome && 336. Palindrome Pairs
2016-07-23 12:54
603 查看
5. Longest Palindromic Substring
Find the longest palindromic substring in string S. You may assume that there exists one unique longest palindromic substring.class Solution { private int resultBegin, resultLen; public String longestPalindrome(String s) { int len = s.length(); if (len < 2) return s; for (int center = 0; center < len - 1; ++center) { extendBothEnds(s, center, center); //when longestPalindrome length is odd extendBothEnds(s, center, center + 1); //when longestPalindrome length is even } return s.substring(resultBegin, resultBegin + resultLen); } private void extendBothEnds(String s, int left, int right) { while (left >= 0 && right < s.length() && s.charAt(left) == s.charAt(right)) { --left; ++right; } ++left; --right; int currentLen = right - left + 1; if (currentLen > resultLen) { resultBegin = left; resultLen = currentLen; } } }
214. Shortest Palindrome
Given a string S, you are allowed to convert it to a palindrome by adding characters in front of it. Find and return the shortest palindrome you can find by performing this transformation.For example:
Given
"aacecaaa", return
"aaacecaaa".
Given
"abcd", return
"dcbabcd".
An intuitive solution, but got TLE.
The idea is to get the longest palindrome prefix, and then reverse the rest of the string and add it to the front. O(n2) complexity.
class Solution { public String shortestPalindrome(String s) { if (s.length() <= 1) return s; int end = s.length(); for (; end >= 1; --end) if (isPalindrome(s.substring(0, end))) break; return new StringBuilder(s.substring(end)).reverse().toString() + s; } private boolean isPalindrome(String s) { for (int left = 0, right = s.length() - 1; left < right; ++left, --right) if (s.charAt(left) != s.charAt(right)) return false; return true; } }
Recursion Solution
Got from: https://discuss.leetcode.com/topic/21068/my-7-lines-recursive-java-solution/4
class Solution { /** * The goal is to complete s into a Palindrome. We could tackle this problem little by little. * <p> * We need to split the string into two parts, s[0,j), s[j,len), such that * s[j, len) is impossible to be matched by s itself, we must prepend a reversed part for it * in front of s. * And we recursively do the same thing for s[0,j) to get this: * reverse(s[j,len)) + f(s[0,j]) + s[j,len) * <p> * One way to find j is that * s[j] is unique but not in the "middle" in the string. */ public String shortestPalindrome(String s) { int j = 0; for (int i = s.length() - 1; i >= 0; --i) //iterate i all the way to 0, such that we try to use s itself to match itself. if (s.charAt(i) == s.charAt(j)) //if j could be matched by i, whather on j itself(mid point), j's right or j's left. ++j; if (j == s.length()) return s; String suffix = s.substring(j); return new StringBuilder(suffix).reverse().toString() + shortestPalindrome(s.substring(0, j)) + suffix; } }
Solution2: KMP algorithm. Knuth-Morris-Pratt Algorithm
https://www.youtube.com/watch?v=GTJr8OvyEVQ
KMP algorithm enables subString search in string S with O(len(subString)+len(S))
c a t a c b # b c a t a c
0 0 0 0 1 0 0 0 1 2 3 4 5
if we don't add #, "aaaaa" wouldn't work.
class Solution { public String shortestPalindrome(String s) { if(s.length() <= 1) return s; String temp = s + "#"+ new StringBuilder(s).reverse().toString(); int[] kmp = getTable(temp); //get the maximum palin part in s starts from 0 return new StringBuilder(s.substring(kmp[kmp.length - 1])).reverse().toString() + s; } /** * ml indicates the max MatchedLength for index i based on Knuth–Morris–Pratt algorithm * "cacfcaca" returns [0, 0, 1, 0, 1, 2, 3, 2] * "babbbabbaba" returns [0, 0, 1, 1, 1, 2, 3, 4, 2, 3, 2] */ private static int[] getTable(String s) { int[] ml = new int[s.length()]; for (int i = 1; i < s.length(); ++i) { /** * loc shows the location/index such that, * s.substring(loc-ml[loc-1],loc) of length ml[loc-1] has fully matched prefix, * we are trying to extend this substring by one more letter, which is at loc */ int loc = i; while (loc >= 1) { //ml[loc - 1] gives how many prefix we have matched, so the next index to compare/match is ml[loc - 1] int nextToMatch = ml[loc - 1]; if (s.charAt(i) == s.charAt(nextToMatch)) { ml[i] = nextToMatch + 1; break; } /** * If we don't find a match, then we try to re-use a shorter match * Think about "cacfcacb", if we cannot match 'f' with 'b', then we cannot use the fully matched "cac". * So, we go to previous letter 'c' at index 2, and check what's length that has been matched until 'c', * and reuse that shorter string. 'c' has a matched length 1, so we will compare 'a'(at 1) with 'b'... * Do this recursively. */ loc = nextToMatch; } } return ml; } }
336. Palindrome Pairs
Given a list of unique words. Find all pairs of distinct indices(i, j)in the given list, so that the concatenation of the two words, i.e.
words[i] + words[j]is a palindrome.
Example 1:
Given
words=
["bat", "tab", "cat"]
Return
[[0, 1], [1, 0]]
The palindromes are
["battab", "tabbat"]
Example 2:
Given
words=
["abcd", "dcba", "lls", "s", "sssll"]
Return
[[0, 1], [1, 0], [3, 2], [2, 4]]
The palindromes are
["dcbaabcd", "abcddcba", "slls", "llssssll"]
Hash Table String Trie
Idea is similar to shortest palindrome, we need to create a trie that reflects the reverse of all words. We match head and tail first, the rest of string/substring should be a palindrome.
public class Solution { class TrieNode { TrieNode[] children = new TrieNode[26]; int wordArrayIndex = -1; //keep the index for current string in the array //keeps the list of word indices in array where the substring(or prefix) is a palindrome List<Integer> list = new ArrayList<>(); } public List<List<Integer>> palindromePairs(String[] words) { List<List<Integer>> results = new ArrayList<>(); TrieNode root = new TrieNode(); for (int i = 0; i < words.length; i++) { //reverse each word and add it to the trie. addWord(root, words[i], i); } for (int i = 0; i < words.length; i++) { search(words[i], i, root, results); } return results; } private void addWord(TrieNode parent, String word, int wordIndex) { for (int i = word.length() - 1; i >= 0; --i) { int pos = word.charAt(i) - 'a'; if (parent.children[pos] == null) parent.children[pos] = new TrieNode(); if (isPalindrome(word, 0, i))//keep those words where the prefix is palindrome parent.list.add(wordIndex); parent = parent.children[pos]; } parent.list.add(wordIndex); parent.wordArrayIndex = wordIndex; } private void search(String word, int wordIndex, TrieNode node, List<List<Integer>> results) { for (int i = 0; i < word.length(); ++i) { //Case 1: word accounts for >= half of the palindrome if (node.wordArrayIndex >= 0 && node.wordArrayIndex != wordIndex //find word matching prefix. && isPalindrome(word, i, word.length() - 1) //rest of the word is palindrome ) results.add(Arrays.asList(wordIndex, node.wordArrayIndex)); node = node.children[word.charAt(i) - 'a']; if (node == null) return; } //Case 2: word accounts for < half of the palindrome //e.g. "abc", "XXXcba", as long as "XXX" part is a palindrome, then we are good. for (int j : node.list) { if (wordIndex == j) continue; results.add(Arrays.asList(wordIndex, j)); } } private boolean isPalindrome(String word, int i, int j) { while (i < j) { if (word.charAt(i++) != word.charAt(j--)) return false; } return true; } }
相关文章推荐
- soft raid5阅读笔记之十--状态标志
- soft raid5阅读笔记之九--MD中的superblock
- 373. Find K Pairs with Smallest Sums && 378. Kth Smallest Element in a Sorted Matrix
- soft raid5阅读笔记之七--MD中的bitmap
- maven install时报错Failed to execute goal org.apache.maven.plugins:maven-compiler-plugin:2.3.2:compile
- Contains Duplicate
- POJ:1995 Raising Modulo Numbers(快速幂)
- 2016 Multi-University Training Contest 2 1006 Fantasia (hdu5739) 【割点 无向图dfs树 树形dp】
- 2016 Multi-university-training-contests-2 1006 点双连通分量
- 在QMainWindow添加控件,无法显示问题
- error: Setup script exited with error: command 'gcc' failed with exit status 1
- E - Doing Homework again hd 1789
- @tailrec注解与“蹦床”机制
- 一颗可靠的时间胶囊:苹果AirPort Time Capsule测评
- HDU Problem—2124 Repair the Wall 【贪心】
- 【杭电】[1789]Doing Homework again
- TypedArray和obtainStyledAttributes使用
- HDOJ 1789 Doing Homework again
- 【杭电】[2124]Repair the Wall
- hdoj5319Painter