336. Palindrome Pairs

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> 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 indices;// indices passing through this node 
            TrieNode(int idx){
                this.idx = idx;
                dsc = new TrieNode[AlphabetSize];
                indices = new LinkedList<>();
            }
        }
    }
    public List> palindromePairs(String[] words) {
        List> 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
My Final Solution:
public class Solution {
    public List> palindromePairs(String[] words) {
        List> pairs = new ArrayList>();
        if(words == null || words.length == 0) return pairs;
        HashMap 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> palindromePairs(String[] words) {
        List> pairs = new LinkedList<>();
        if (words == null) return pairs;
        HashMap 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> palindromePairs(String[] words) {
        List> pairs = new LinkedList<>();
        if(words == null) return pairs;
        Map map = new HashMap<>();
        for(int i=0; i

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

Best Solution: (140ms)
public class Solution {
    public List> palindromePairs(String[] words) {
        List> res = new ArrayList>();
        if(words == null || words.length == 0) return res;
        HashMap 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 list = new ArrayList();
                        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 list = new ArrayList();
                        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

你可能感兴趣的:(336. Palindrome Pairs)