资讯专栏INFORMATION COLUMN

Palindrome Pairs & Shortest Palindrome

CNZPH / 758人阅读

摘要:部分是回文的,在里面找是否有的。这里的范围是,最小是,因为要保证是两个单词,最大是,这时候要找出另一个和他相反的串。判断为回文,可以直接暴力,每个都判断一次。两个方向都找一遍就可能出现重复的情况,注意避免重复。例如,结果应该是。

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

    摘要:题目链接找到从头开始最长的那么只要把的加到前面就是结果了。找的过程可以用来做优化,由于,那么就照着里面见数组的方法来查,最后就是的长度,注意两个并在一起的要加分隔符,防止算的出问题。 214. Shortest Palindrome 题目链接:https://leetcode.com/problems... 找到string从头开始最长的palindrome substring:s[0...

    beita 评论0 收藏0
  • [LeetCode] 214. Shortest Palindrome

    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...

    liangdas 评论0 收藏0
  • [Leetcode] Shortest Palindrome 最短回文拼接法

    摘要:第二个是,因为在第个位置,可以有最长为的相同前后缀,依次类推。匹配时分为几种情况字母相同,则和都加,且,因为后缀匹配的长度是前缀的长度加。注意为了方便处理空字符串,我们在反转拼接的时候中间加了,这个字符要保证不会出现在字符串中。 Shortest Palindrome Given a string S, you are allowed to convert it to a palin...

    Chiclaim 评论0 收藏0
  • 336. Palindrome Pairs

    摘要:容易出的两个地方以为例。这两个互为的在尾部加上也就是在头部加上所以后部分不能为空,否则就和头部为空的情况重复了。空间复杂度因为用了额外的来储存,需要空间。时间复杂度每个分为两个部分,调用前后两部分总长度为所以每次调用为一共次。 Given a list of unique words, find all pairs of distinct indices (i, j) in the g...

    Guakin_Huang 评论0 收藏0
  • LeetCode 336. Palindrome Pairs

    摘要:描述给定一组唯一的单词,找出所有不同的索引对,使得列表中的两个单词,,可拼接成回文串。遍历每一个单词,对每一个单词进行切片,组成和。 Description Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenatio...

    TigerChain 评论0 收藏0

发表评论

0条评论

最新活动
阅读需要支付1元查看
<