美文网首页
336. Palindrome Pairs

336. Palindrome Pairs

作者: bin_guo | 来源:发表于2018-07-01 15:01 被阅读0次

Leetcode: 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"]

Strategy:
  1. List of words, needs one layer of looping
  2. Number of letters in a word is not fixed, needs deep lool into each word, another layer of looping
  3. The order of compositing a pair, (a, b) or (b, a), needs to be separated as two times
  4. When looping, the front part is starting from index 0, and the second part must be ending with the index of length of letters
  5. Either the front or the second part could be searched in the list of words, and the other part should be tested for palindorme
New Solution:
class Solution {
    static class Trie{
        TrieNode root;
        final static int AlphabetSize = 26;
        Trie(){
            root = new TrieNode(-1);
        }
        public void add(String word, int id){
            TrieNode head = root;
            for(int i = word.length()-1;i>=0; i--){
                int j = word.charAt(i) -'a';
                if(head.dsc[j] == null){
                    head.dsc[j] = new TrieNode(-1);
                }
                if(isPalindrome(word,0,i)) 
                    head.indices.add(id);//can cover "" string cases. e.g. for string "aaa",root will have its index
                head = head.dsc[j];
            }
            head.indices.add(id);
            head.idx = id;
        }
        public void search(String word,int id, List<List<Integer>> rs){
            TrieNode head = root;
            for(int i=0; i< word.length(); i++){
                if(head.idx!=-1 && isPalindrome(word,i,word.length()-1))
                    rs.add(Arrays.asList(id,head.idx));
                int j = word.charAt(i) - 'a';
                if(head.dsc[j] == null)
                    return ;
                head = head.dsc[j];
            }
            for(int a : head.indices){
                if(a!=id)
                    rs.add(Arrays.asList(id,a));
            }
        }
        private boolean isPalindrome(String str1, int i, int j){
            while(i<=j){
                if(str1.charAt(i++)!=str1.charAt(j--)){
                    return false;
                }   
            }
            return true;
        }
        static class TrieNode{
            int idx; // -1 means no words ends at this node. i means words[i] ends here
            TrieNode[] dsc;
            List<Integer> indices;// indices passing through this node 
            TrieNode(int idx){
                this.idx = idx;
                dsc = new TrieNode[AlphabetSize];
                indices = new LinkedList<>();
            }
        }
    }
    public List<List<Integer>> palindromePairs(String[] words) {
        List<List<Integer>> rs = new LinkedList<>();
        Trie dict = new Trie();
        for(int i =0; i< words.length; i++) 
            dict.add(words[i],i);
        for(int i = 0; i<words.length; i++)
            dict.search(words[i],i,rs);
        return rs;
    }
}
My Final Solution:
public class Solution {
    public List<List<Integer>> palindromePairs(String[] words) {
        List<List<Integer>> pairs = new ArrayList<List<Integer>>();
        if(words == null || words.length == 0) return pairs;
        HashMap<String, Integer> map = new HashMap<>();
        for(int i = 0; i < words.length; i++) map.put(words[i], i);
        for(int i = 0; i < words.length; i++){
            for(int j = 0; j <= words[i].length(); j++){ // <= not <
                String frontStr = words[i].substring(0, j);
                String backStr = words[i].substring(j);
                
                if(isPalindrome(frontStr)){
                    String backRev = new StringBuilder(backStr).reverse().toString();
                    if(map.containsKey(backRev) && map.get(backRev) != i){
                        pairs.add(Arrays.asList(new Integer[]{map.get(backRev), i}));
                    }
                } 
                if(isPalindrome(backStr) && backStr.length() != 0){ //exam the length for backString is 0 or not
                    String frontRev = new StringBuilder(frontStr).reverse().toString();
                    if(map.containsKey(frontRev) && map.get(frontRev) != i){
                        pairs.add(Arrays.asList(new Integer[]{i,map.get(frontRev)}));
                    }
                }
            }
        }
        return pairs;
    }
    
    private boolean isPalindrome(String s) {
        for (int i = 0; i < s.length()/2; ++ i) // half of length
            if (s.charAt(i) != s.charAt(s.length()-1-i))
                return false;
        return true;
    }
}
Referenced Solutions:
public class Solution {
    public List<List<Integer>> palindromePairs(String[] words) {
        List<List<Integer>> pairs = new LinkedList<>();
        if (words == null) return pairs;
        HashMap<String, Integer> map = new HashMap<>();
        for (int i = 0; i < words.length; ++ i) map.put(words[i], i);
        for (int i = 0; i < words.length; ++ i) {
            int l = 0, r = 0;
            while (l <= r) {
                String s = words[i].substring(l, r);
                Integer j = map.get(new StringBuilder(s).reverse().toString());
                if (j != null && i != j && isPalindrome(words[i].substring(l == 0 ? r : 0, l == 0 ? words[i].length() : l)))
                    pairs.add(Arrays.asList(l == 0 ? new Integer[]{i, j} : new Integer[]{j, i}));
                if (r < words[i].length()) ++r;
                else ++l;
            }
        }
        return pairs;
    }
    
    private boolean isPalindrome(String s) {
        for (int i = 0; i < s.length()/2; ++ i)
            if (s.charAt(i) != s.charAt(s.length()-1-i))
                return false;
        return true;
    }
}
class Solution {
    public List<List<Integer>> palindromePairs(String[] words) {
        List<List<Integer>> pairs = new LinkedList<>();
        if(words == null) return pairs;
        Map<String, Integer> map = new HashMap<>();
        for(int i=0; i<words.length; i++) map.put(words[i], i);
        for(int index=0; index<words.length; index++){
            String cur = words[index];
            for(int j=0; j<cur.length(); j++){
                String sub = cur.substring(0, j+1);
                StringBuilder reverse = new StringBuilder(sub).reverse();
                if(map.containsKey(reverse.toString()) && map.get(reverse.toString())!=index && isPalindrome(cur.substring(j+1)))
                    pairs.add(Arrays.asList(new Integer[]{index, map.get(reverse.toString())}));
            }
            int j = cur.length() - 1;
            for(int i=1; i<cur.length(); i++){
                String sub = cur.substring(i, j+1);
                StringBuilder reverse = new StringBuilder(sub).reverse();
                if(map.containsKey(reverse.toString()) && map.get(reverse.toString())!=index && isPalindrome(cur.substring(0, i)))
                    pairs.add(Arrays.asList(new Integer[]{map.get(reverse.toString()), index}));
            }
        }
        return pairs;
    }
    
    
    private boolean isPalindrome(String s) {
        for (int i = 0; i < s.length()/2; ++ i)
            if (s.charAt(i) != s.charAt(s.length()-1-i))
                return false;
        return true;
    }
}

Referenced from
Author:Jeanz
Link:https://www.jianshu.com/p/f08f2afe9681

Best Solution: (140ms)
public class Solution {
    public List<List<Integer>> palindromePairs(String[] words) {
        List<List<Integer>> res = new ArrayList<List<Integer>>();
        if(words == null || words.length == 0) return res;
        HashMap<String, Integer> map = new HashMap<>();
        for(int i = 0; i < words.length; i++) map.put(words[i], i);
        for(int i = 0; i < words.length; i++){
            for(int j = 0; j <= words[i].length(); j++){
                String str1 = words[i].substring(0, j);
                String str2 = words[i].substring(j);
                
                if(isPalindrome(str1)){
                    String str2rvs = new StringBuilder(str2).reverse().toString();
                    if(map.containsKey(str2rvs) && map.get(str2rvs) != i){
                        List<Integer> list = new ArrayList<Integer>();
                        list.add(map.get(str2rvs));
                        list.add(i);
                        res.add(list);
                    }
                } 
                if(isPalindrome(str2) && str2.length() != 0){
                    String str1rvs = new StringBuilder(str1).reverse().toString();
                    if(map.containsKey(str1rvs) && map.get(str1rvs) != i){
                        List<Integer> list = new ArrayList<Integer>();
                        list.add(i);
                        list.add(map.get(str1rvs));
                        res.add(list);
                    }
                }
            }
        }
        return res;
    }
    
    public boolean isPalindrome(String s){
        int left = 0, right = s.length() - 1;
        while(left < right){
            if(s.charAt(left++) != s.charAt(right--)) return false;
        }
        return true;
    }
}

Referenced from
Author: 大米中的大米
Link: https://segmentfault.com/a/1190000008917798

相关文章

  • 2019-04-07

    LeetCode 336. Palindrome Pairs Description Given a list o...

  • 336. Palindrome Pairs

    Leetcode: 336.Palindrome PairsGiven a list of unique word...

  • 336. Palindrome Pairs

    这一题 想到的就是一个o(n2)的方法,会超时,discussion里面有个写法很6,我重新写会有些case过不去...

  • LeetCode 336. Palindrome Pairs

    对每个word,如果它翻转过来之后[:n]或者[n:]和map中已有的key相同,且剩下的一部分是palindro...

  • [leetcode] 336. Palindrome Pairs

    Given a list of unique words, find all pairs of distinct ...

  • Leetcode 336. Palindrome Pairs

    文章作者:Tyan博客:noahsnail.com[http://noahsnail.com] | CSDN[ht...

  • 8.19 - hard - 70

    336. Palindrome Pairs 基本想出来是怎么做,只是一上来就想去优化,结果想的有点乱,其实最好的方...

  • Palindrome Pairs

    Given a list of unique words, find all pairs of distinct ...

  • Palindrome Pairs

    题目Given a list of unique words, find all pairs of distinc...

  • Palindrome Pairs

    题目来源给一个字符串数组,求能组成回文串的两个元素的。就是比较烦,但是倒不是很难。代码如下:

网友评论

      本文标题:336. Palindrome Pairs

      本文链接:https://www.haomeiwen.com/subject/yagcuftx.html