zoukankan      html  css  js  c++  java
  • 336. Palindrome Pairs(can't understand)

    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:

    Input: ["abcd","dcba","lls","s","sssll"]
    Output: [[0,1],[1,0],[3,2],[2,4]] 
    Explanation: The palindromes are ["dcbaabcd","abcddcba","slls","llssssll"]
    

    Example 2:

    Input: ["bat","tab","cat"]
    Output: [[0,1],[1,0]] 
    Explanation: The palindromes are ["battab","tabbat"]
    
     

    Approach #1: C++.

    class Solution {
    public:
        vector<vector<int>> palindromePairs(vector<string>& words) {
            int size = words.size();
            int mul = 1000000007;
            
            int max_len = 0;
            vector<vector<int>> hash_pre(size, vector<int>());
            vector<vector<int>> hash_suf(size, vector<int>());
            
            vector<int> temp(2, 0);
            vector<vector<int>> ret;
            
            for (int i = 0; i < size; ++i) {
                hash_pre[i] = vector<int>(words[i].size(), 0);
                hash_suf[i] = vector<int>(words[i].size(), 0);
                
                if (words[i].size() == 0) continue;
                hash_pre[i][0] = words[i][0];
                hash_suf[i][words[i].size()-1] = words[i][words[i].size()-1];
                for (int j = 1; j < words[i].size(); ++j) {
                    hash_pre[i][j] = hash_pre[i][j-1] * mul + words[i][j];
                }
                for (int j = (int)words[i].size()-2; j >= 0; --j) {
                    hash_suf[i][j] = hash_suf[i][j+1] * mul + words[i][j];
                }
                max_len = max(max_len, (int)words[i].size());
            }
            
            vector<int> exp(max_len + 1, 0);
            exp[0] = 1;
            for (int i = 1; i <= max_len; ++i)
                exp[i] = exp[i-1] * mul;
            for (int i = 0; i < size; ++i)
                for (int j = 0; j < size; ++j) {
                    if (i == j) continue;
                    int len = words[i].size() + words[j].size();
                    int hash_left = 0, hash_right = 0;
                    int left_len = len / 2;
                    
                    if (left_len != 0) {
                        if (words[i].size() >= left_len) {
                            hash_left = hash_pre[i][left_len-1];
                        } else {
                            if (words[i].size() == 0)
                                hash_left = hash_pre[j][left_len-1];
                            else {
                                int right_pre = left_len - words[i].size();
                                hash_left = hash_pre[i][words[i].size() - 1] * exp[right_pre] + hash_pre[j][right_pre-1];
                            }
                        }
                    }
                    
                    if (left_len != 0) {
                        if (words[j].size() >= left_len) {
                            hash_right = hash_suf[j][words[j].size()-left_len];
                        } else {
                            if (words[j].size() == 0)
                                hash_right = hash_suf[i][words[i].size()-left_len];
                            else {
                                int left_pre = left_len - words[j].size();
                                hash_right = hash_suf[j][0] * exp[left_pre] + hash_suf[i][words[i].size()-left_pre];
                            }
                        }
                    }
                    
                    if (hash_left == hash_right) {
                        temp[0] = i, temp[1] = j;
                        ret.push_back(temp);
                    }
                    
                }
            return ret;
        }
    };
    

    Runtime816 ms, faster than 3.13% of C++ online submissions for Palindrome Pairs.

    Approach #2: Java.

    class Solution {
        public List<List<Integer>> palindromePairs(String[] words) {
            Map<String, Integer> index = new HashMap<>();
            Map<String, Integer> revIndex = new HashMap<>();
            String[] revWords = new String[words.length];
            for (int i = 0; i < words.length; ++i) {
                String s = words[i];
                String r = new StringBuilder(s).reverse().toString();
                index.put(s, i);
                revIndex.put(r, i);
                revWords[i] = r;
            }
            List<List<Integer>> result = new ArrayList<>();
            result.addAll(findPairs(words, revWords, revIndex, false));
            result.addAll(findPairs(revWords, words, index, true));
            return result;
        }
        
        private static List<List<Integer>> findPairs(String[] words, String[] revWords, Map<String, Integer> revIndex, boolean reverse) {
            List<List<Integer>> result = new ArrayList<>();
            for (int i = 0; i < words.length; ++i) {
                String s = words[i];
                for (int k = reverse ? 1 : 0; k <= s.length(); ++k) {
                    Integer j = revIndex.get(s.substring(k));
                    if (j != null && j != i) {
                        if (s.regionMatches(0, revWords[i], s.length() - k, k)) {
                            result.add(reverse ? Arrays.asList(i, j) : Arrays.asList(j, i));
                        }
                    }
                }
            }
            return result;
        } 
    }
    

      

    Approach #3: Python.

    class Solution(object):
        def palindromePairs(self, words):
            """
            :type words: List[str]
            :rtype: List[List[int]]
            """
            wordict = {}
            res = []
            for i in range(len(words)):
                wordict[words[i]] = i
            for i in range(len(words)):
                for j in range(len(words[i])+1):
                    tmp1 = words[i][:j]
                    tmp2 = words[i][j:]
                    if tmp1[::-1] in wordict and wordict[tmp1[::-1]] != i and tmp2 == tmp2[::-1]:
                        res.append([i, wordict[tmp1[::-1]]])
                    if j != 0 and tmp2[::-1] in wordict and wordict[tmp2[::-1]] != i and tmp1 == tmp1[::-1]:
                        res.append([wordict[tmp2[::-1]], i])
                        
            return res
    

      

    Time SubmittedStatusRuntimeLanguage
    a few seconds ago Accepted 144 ms java
    27 minutes ago Accepted 864 ms python
    3 hours ago Accepted 816 ms cpp
    永远渴望,大智若愚(stay hungry, stay foolish)
  • 相关阅读:
    二、Java面向对象(11)_final修饰符
    二、Java面向对象(10)_代码块
    二、Java面向对象(9)_面向对象——多态思想
    二、Java面向对象(8)_继承思想——Object类
    二、Java面向对象(8)_继承思想——子类初始化过程
    二、Java面向对象(8)_继承思想——super关键字
    二、Java面向对象(8)_继承思想——方法覆盖
    WP8.1 RT 生命周期详解‏‏‏‏‏‏‏‏‏‏‏‏‏
    将十六进制色值转换成Color
    WindowsPhone8.1RT建立空白应用挂起没反应的解决方案
  • 原文地址:https://www.cnblogs.com/h-hkai/p/9948425.html
Copyright © 2011-2022 走看看