摘要:部分是回文的,在里面找是否有的。这里的范围是,最小是,因为要保证是两个单词,最大是,这时候要找出另一个和他相反的串。判断为回文,可以直接暴力,每个都判断一次。两个方向都找一遍就可能出现重复的情况,注意避免重复。例如,结果应该是。
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> palindromePairs(String[] words) { Map
map = new HashMap(); for(int i = 0; i < words.length; i++) { map.put(new StringBuilder(words[i]).reverse().toString(), i); } List > 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); } }
文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。
转载请注明本文地址:https://www.ucloud.cn/yun/66572.html
摘要:题目链接找到从头开始最长的那么只要把的加到前面就是结果了。找的过程可以用来做优化,由于,那么就照着里面见数组的方法来查,最后就是的长度,注意两个并在一起的要加分隔符,防止算的出问题。 214. Shortest Palindrome 题目链接:https://leetcode.com/problems... 找到string从头开始最长的palindrome substring:s[0...
Problem 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. Exa...
摘要:第二个是,因为在第个位置,可以有最长为的相同前后缀,依次类推。匹配时分为几种情况字母相同,则和都加,且,因为后缀匹配的长度是前缀的长度加。注意为了方便处理空字符串,我们在反转拼接的时候中间加了,这个字符要保证不会出现在字符串中。 Shortest Palindrome Given a string S, you are allowed to convert it to a palin...
摘要:容易出的两个地方以为例。这两个互为的在尾部加上也就是在头部加上所以后部分不能为空,否则就和头部为空的情况重复了。空间复杂度因为用了额外的来储存,需要空间。时间复杂度每个分为两个部分,调用前后两部分总长度为所以每次调用为一共次。 Given a list of unique words, find all pairs of distinct indices (i, j) in the g...
摘要:描述给定一组唯一的单词,找出所有不同的索引对,使得列表中的两个单词,,可拼接成回文串。遍历每一个单词,对每一个单词进行切片,组成和。 Description Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenatio...
阅读 3403·2021-11-24 10:30
阅读 3271·2021-11-22 15:29
阅读 3708·2021-10-28 09:32
阅读 1256·2021-09-07 10:22
阅读 3338·2019-08-30 15:55
阅读 3621·2019-08-30 15:54
阅读 3496·2019-08-30 15:54
阅读 2834·2019-08-30 15:44