[Leetcode] 336. Palindrome Pairs 解题报告

来源:互联网 发布:对银行业的看法 知乎 编辑:程序博客网 时间:2024/06/07 12:01

题目

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

思路

最近连续几道题目都是hard级别的,而且又比较麻烦,搞得我心力交瘁的。

言归正传,这道题目的思路是将所有的单词逆序加入hash表中, 然后再遍历一遍数组, 然后会有两种情况:

1)将单词的前一部分如果可以在hash表中找到匹配说明这部分是可以回文的, 如果这个单词剩下的部分也是回文, 那么这两个单词就可以配成回文. 例如aabbcc和bbaa, 其中bbaa在hash表中是以逆序存在的, 即aabb, 那么当我们遍历到aabbcc的时候其前半部分aabb可以在hash表中查到, 并且剩余部分cc是回文, 因此他们可以构成回文;

2)如果单词的后一部分可以在hash表中查到, 并且其前一部分是回文, 他们也可以构成匹配. 例如aabb和ccbbaa, 其中aabb在hash表中是以bbaa存在的. 当我们遍历到ccbbaa的时候, 其后一部分bbaa可以在hash表中查到存在, 并且其前一部分cc是回文, 因此他们也可以构成回文。

有一些特殊的case需要注意:

1)要防止与其本身进行匹配。

2)当存在空串时, 就会复杂一些, 比如["a", ""], 这种情况应该输出[[0, 1] [1, 0]]. 因此空串也应该在作为其前缀和后缀进行检测. 但是这种情况又会引起另外的问题, 例如aabb和bbaa, 当我们将单词划分为左右两部分并且其前半部分为空串或这后半部分为空串时都会匹配, 也就是遍历到aabb时会产出两个匹配, 即aabb作为前缀, 空串作为后缀 和空串作为前缀, aabb作为后缀时. 而遍历到单词bbaa时又会重复匹配一次, 因此我们需要引入另外一个条件, 即在分别判断将当前单词的前一部分作为前缀和后一部分作为后缀的时候, 其前缀和后缀不能同时等于单词本身。

代码

class Solution {public:    vector<vector<int>> palindromePairs(vector<string>& words) {        unordered_map<string, int> hash;            // map from string to index        vector<vector<int>> result;        for(int i = 0; i < words.size(); i++) {            hash[words[i]] = i;        }        for(int i = 0; i < words.size(); i++) {     // check the reverse string            reverse(words[i].begin(), words[i].end());            int len = words[i].size();            for(int j = 0; j <= len; ++j) {         // check the left part and the right part, respectively                string left =words[i].substr(0, j), right = words[i].substr(j);                if(hash.count(left) && isPalin(right) && hash[left] != i) {                    result.push_back(vector<int>{hash[left], i});                }                // (len - j) is the length of the substring right, and it should be smaller than the length of words[i]                if(hash.count(right) && isPalin(left) && hash[right] != i && len > len - j) {                    result.push_back(vector<int>{i, hash[right]});                }            }        }        return result;    }private:    bool isPalin(string &str) {        for(int i = 0; i < str.size() / 2; ++i) {            if(str[i] != str[str.size() - i - 1]) {                return false;            }        }        return true;    }};

原创粉丝点击