leetcode【336】【tag String】Palindrome Pairs 【c++,beats 70%】

问题描述:

Given a list of unique words, return all the pairs of the distinct indices (i, j) in the given list, so that the concatenation of the two words words[i] + words[j] is a palindrome.

 

Example 1:

Input: words = ["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: words = ["bat","tab","cat"]
Output: [[0,1],[1,0]]
Explanation: The palindromes are ["battab","tabbat"]

Example 3:

Input: words = ["a",""]
Output: [[0,1],[1,0]]

 

Constraints:

  • 1 <= words.length <= 5000
  • 0 <= words[i].length <= 300
  • words[i] consists of lower-case English letters.

源码:

害,这两月忙了点别的事情,一直就没刷题了,这下手感生疏的很,想了半天也没啥思路,解法二就是我们瞎想的。

解法1:

需要借助一个特性,之前还不知道,就是set他会自动排序,把小的放在前面,大的放在后面。

  1. 首先用map存储每个字符串的位置,用set存储出现过的字符串大小;
  2. 对于每个字符串处理的步骤主要包括以下部分:
  • 反转字符串,若反转后的字符串若在map中且位置不是自身,就加入result;
  • 查找比字符串长度小的字符串能否和本串拼接,此时需要满足前半部分或者后半部分的反转能够找到,且剩余部分自身为回文;
  • 若字符串前半部分是回文,后半部分的反转值可以在map中找到,则可以加入result;
  • 同理若字符串前半部分是回文,后半部分的反转值可以在map中找到,则可以加入result;
class Solution {
private:
    bool isvalid (string str, int begin, int end) {
        while (begin < end) {
            if (str[begin++] != str[end--]) {
                return false;
            }
        }
        return true;
    }
public:
    vector<vector<int>> palindromePairs(vector<string>& words) {
        vector<vector<int>> result;
        if (words.size() == 0) {
            return result;
        }
        map<string, int> store;
        set<int> lenSet;
        for (int i=0; i<words.size(); i++) {
            store[words[i]] = i;
            lenSet.insert(words[i].length());
        }
        for (int i=0; i<words.size(); i++) {
            string tmp = words[i];
            int len = tmp.size();
            reverse(tmp.begin(), tmp.end());
            if (store.count(tmp) && store[tmp]!=i) {
                result.push_back(vector<int> {i, store[tmp]});
            }
            auto endFlag = lenSet.find(len);
            for (auto it=lenSet.begin(); it!=endFlag; it++) {
                int d = *it;
                if (isvalid(tmp, 0, len-d-1) && store.count(tmp.substr(len-d))) {
                    result.push_back(vector<int> {i, store[tmp.substr(len-d)]});
                }
                if (isvalid(tmp, d, len-1) && store.count(tmp.substr(0, d))) {
                    result.push_back(vector<int> {store[tmp.substr(0, d)], i});
                }
            }
        }
        return result;
    }
};

解法2:失败

相当于暴力的做法,只是如果验证words[i]+words[j]是回文,只要words[i]和words[j]长度相等,则words[j]+words[i]也是回文。最终超时。

class Solution {
private:
    bool isPail(string first, string second) {
        string newStr = first+second;
        int left=0, right=newStr.length()-1;
        while (left < right) {
            if (newStr[left] != newStr[right]) {
                return false;
            }
            left++;
            right--;
        }
        return true;
    }
public:
    vector<vector<int>> palindromePairs(vector<string>& words) {
        vector<vector<int>> result;
        if (words.size() == 0) {
            return result;
        }
        set<pair<int,int>> store;
        for (int i=0; i<words.size(); i++) {
            for (int j=0; j<words.size(); j++) {
                if (i == j || store.count(make_pair(i, j))) {
                    continue;
                }
                if (isPail(words[i], words[j])) {
                    result.push_back(vector<int>{i, j});
                    store.insert(make_pair(i, j));
                    if (words[i].length() == words[j].length()) {
                        result.push_back(vector<int>{j, i});
                        store.insert(make_pair(j, i));
                    }
                }
            }
        }
        return result;
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值