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

这道题是在字符串中找能够构成回文的字符串对,题目难度为Hard。

将构成回文的两个字符串记为s1和s2,构成回文的形式是s1+s2。如果s1长度比s2小,将s2分为左右两部分ls和rs,其中rs和s1长度相等,则rs倒序后和s1是相同的,同时ls自身也是回文;如果s1长度比s2大,将s1分为左右两部分ls和rs,其中ls和s2长度相等,则ls倒序后和s2是相同的,同时rs自身也是回文;如果s1和s2长度相等,相当于ls或rs为空字符串,则s1倒序后和s2相同。

依照上述分析,我们可以遍历字符串数组,针对每个字符串在任意位置将其分为左右两部分ls和rs(可以为空字符串),然后判断两部分是否是回文,如果ls是回文,相当于将本字符串放置在回文字符串的右边,判断rs倒序后是否在原始字符串中,如果在则构成回文(注意判断是否是同一字符串);同理,如果rs是回文,相当于将本字符串放置在回文字符串的左边,判断ls倒序后是否在原始字符串中,如果在则构成回文(同样需要判断是否是同一字符串)。这里需要注意的是长度相同的两个字符串如果构成回文,两者相对位置可以是s1+s2或者s2+s1,在各自的判断循环中两种情况都会认定为回文,会出现重复的下标对,所以在循环中判断rs回文的同时加了不空的判断,相当于各自减少了一种情况,不影响两者长度不等的情况以及最终结果。具体代码:

class Solution {
    bool isPalindrome(string s) {
        int l = 0, r = s.size()-1;
        while(s[l] == s[r]) {
            ++l;
            --r;
        }
        return l>r;
    }
public:
    vector<vector<int>> palindromePairs(vector<string>& words) {
        vector<vector<int>> ret;
        unordered_map<string, int> hash;
        
        for(int i=0; i<words.size(); ++i) hash[words[i]] = i;
        for(int i=0; i<words.size(); ++i) {
            for(int j=0; j<=words[i].size(); ++j) {
                string ls = words[i].substr(0, j);
                string rs = words[i].substr(j);
                if(isPalindrome(ls)) {
                    reverse(rs.begin(), rs.end());
                    if(hash.find(rs) != hash.end() && hash[rs] != i) {
                        ret.push_back(vector<int>{hash[rs], i});
                    }
                }
                if(!rs.empty() && isPalindrome(rs)) {
                    reverse(ls.begin(), ls.end());
                    if(hash.find(ls) != hash.end() && hash[ls] != i) {
                        ret.push_back(vector<int>{i, hash[ls]});
                    }
                }
            }
        }
        
        return ret;
    }
};

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值