Palindrome Pairs
链接:https://leetcode.com/problems...
这道题没想出来思路,参考了这个博客的内容:
http://bookshadow.com/weblog/...
把一个单词分为两个部分:left, right。right部分是回文的,在words里面找是否有reverse的left。这里的left范围是(0, len(word)),最小是0,因为要保证是两个单词,最大是len(word),这时候要找出另一个和他相反的串。根据题目的意思,一个单词只能用一次,而且words里面单词都是unqiue的。
现在的问题就在于如果判断right是否为回文,以及如何找到left的reverse串。判断right为回文,可以直接暴力,每个right都判断一次。找left可以用trie tree或者hashmap。可能出现ab, ccba这种第二个数比一个数长的情况,所以不光要从左到右看,还要从右往左看。两个方向都找一遍就可能出现重复的情况,注意避免重复。
两个词形成的string一样不算重复,只有当两个词的组合重复时才算重复。例如: ["", "aa"],结果应该是[(0,1), (1,0)]。那么什么时候可能出现重复呢?["ab", "ba"],这种两个单词形成了palindrome,如果在ab和ba的两边都查一遍肯定会重复。可以看出规律是当map里面有其中一个词的reverse时,就少算一边即可。
public class Solution {
public List<List<Integer>> palindromePairs(String[] words) {
Map<String, Integer> map = new HashMap();
for(int i = 0; i < words.length; i++) {
map.put(new StringBuilder(words[i]).reverse().toString(), i);
}
List<List<Integer>> result = new ArrayList();
for(int i = 0; i < words.length; i++) {
String cur = words[i];
int n = cur.length();
for(int j = 0; j <= n; j++) {
// left: (0, j), right: (j, n)
// right is palindrome and find reversed left
String left = cur.substring(0, j);
String right = cur.substring(j, n);
if(isPalindrome(right) && map.containsKey(left) && map.get(left) != i) {
result.add(Arrays.asList(i, map.get(left)));
}
// left is palindrome and find reversed right
if(isPalindrome(left) && map.containsKey(right) && map.get(right) != i) {
// avoid duplication
if(j == 0 && map.containsKey(cur) && map.get(cur) != i) continue;
result.add(Arrays.asList(map.get(right), i));
}
}
}
return result;
}
private boolean isPalindrome(String s) {
int i = 0, j = s.length() - 1;
while(i < j) {
if(s.charAt(i) != s.charAt(j)) return false;
i++; j--;
}
return true;
}
}
这个博客还用了一种set的方法:
http://www.cnblogs.com/grandy...
暂时还没看懂,明天再看下。。
Shortest Palindrome
题目链接:https://leetcode.com/problems...
这道题和“ Longest Palindromic Substring ” 是一个意思,不同的是这个palindrome string必须要从index = 0开始。最简单的方法就是一个一个试。超时了。。。
Manacher's Algorithm
这个算法是用来找最长回文字串的,利用的是回文的对称信息或者说是prefix信息。
public class Solution {
public String longestPalindrome(String s) {
// base case
if(s == null || s.length() <= 1) return s;
// Manacher Algorithm
/* new index: 0 1 2 3 4 5 6
old index: # 0 # 1 # 2 #
m c i r
*/
// An array to store the max length at each center
int n = s.length() * 2 + 1;
int[] pivot = new int[n];
pivotInitial(pivot, s);
// find the maximum length
int maxLen = 0;
int center = 0;
for(int i = 0; i < n; i++) {
if(pivot[i] > maxLen) {
maxLen = pivot[i];
center = i;
}
}
int lo = (center - maxLen) / 2;
int hi = lo + maxLen;
return s.substring(lo, hi);
}
// Manacher
/* new index: 0 1 2 3 4 5 6
old index: # 0 # 1 # 2 #
m c i r
*/
private void pivotInitial(int[] arr, String s) {
// center and maximum reachable index
int c = 0, r = 0;
for(int i = 0; i < arr.length; i++) {
int diff = r - i;
// mirror to i with pivot c
int m = c - (i - c);
// the maximum palindrome is in the reachable
if(diff >= 0 && arr[m] < diff) {
arr[i] = arr[m];
}
else {
// if i > r, then just start from i
int left = i / 2 - 1;
int right = i / 2 + i % 2;
// start from the index that exceed the reachable index
if(diff >= 0) {
left -= diff / 2;
right += diff / 2;
}
// update center and maximum reachable
arr[i] = len(s, left, right);
c = i;
r = i + arr[i];
}
}
}
private int len(String s, int left, int right) {
while(left >= 0 && right <= s.length() - 1) {
if(s.charAt(left) == s.charAt(right)) {
left--; right++;
}
else break;
}
return right - left - 1;
}
}
KMP
这个算法是用来找substring的,利用的是substring自身的prefix信息。
// KMP algorithm
public class KMPSubstringSearch {
/* compute the prefix array for the pattern string */
private int[] prefixArray(String pattern) {
int[] pre = new int[pattern.length()];
// pre[0] = 0, pre[i] means the index of prefix
// index used to store the position of matched prefix
int index = 0;
int i = 1;
while(i < pattern.length()) {
if(pattern.charAt(i) == pattern.charAt(index)) {
pre[i] = index + 1;
i++; index++;
}
else {
if(index == 0) {
pre[i] = 0;
i++;
}
else {
index = pre[index-1];
}
}
}
return pre;
}
// kmp, pattern match, return the position
// if no match, return -1
private int kmp(String text, String pattern) {
int[] pre = prefixArray(pattern);
int i = 0; int j = 0;
char[] ctext = text.toCharArray();
char[] cpattern = pattern.toCharArray();
while(i < ctext.length && j < cpattern.length) {
// match
if(ctext[i] == cpattern[j]) {
i++; j++;
}
// not match
else {
// first char of the pattern string
if(j == 0) {
i++;
}
else {
j = pre[j-1];
}
}
}
if(j == cpattern.length) {
return i-j;
}
else return -1;
}
public static void main(String args[]) {
String text = "abdacabc";
String pattern = "abc";
KMPSubstringSearch test = new KMPSubstringSearch();
int result = test.kmp(text, pattern);
System.out.println(result);
}
}
**粗体** _斜体_ [链接](http://example.com) `代码` - 列表 > 引用
。你还可以使用@
来通知其他用户。