leetcode 336. Palindrome Pairs

来源:互联网 发布:九本女王升级数据2017 编辑:程序博客网 时间:2024/05/16 01:38

一开始的思路就是遍历所有的pair,判断这个pair拼接起来是不是回文串,首先,还是拿例子说明

["abcd", "dcba", "lls", "s", "sssll"] 答案:[[0, 1], [1, 0], [3, 2], [2, 4]]。当我遍历到i=2,j=4的时候,即words[i] = "lls",words[j] = "sssll",由于words[i] = "lls"的长度是小于words[j] = "sssll",所以要将”sssll“拆分成两部分,有一部分必须是”lls“的反转串,剩下的那一部分必须是回文串,这样的话words[j] = "sssll"才能拼到words[i] = "lls"的右边,这种情况是len(words[i]) <= len(words[j]);另外一种情况是len(words[i]) > len(words[j]),比如当遍历到i=4,j=2的时候,即words[i] = "sssll",words[j] = "lls",此时words[i] = "sssll"的长度是大于words[j] = "lls",处理的方法与前一种情况类似。实现代码如下:

class Solution {public:    vector<vector<int>> palindromePairs(vector<string>& words) {        vector<vector<int>> resultVec;        for (int i = 0; i < words.size(); i++) {            for (int j = 0; j < words.size(); j++) {                if (i == j) {                    continue;                }                bool palidromeFlag = true, reverseFlag = true;                if (words[i].size() <= words[j].size()) {                    palidromeFlag = isPalidrome(words[j].substr(0, int(words[j].size()) - int(words[i].size())));                    reverseFlag = isReverse(words[i], words[j].substr(int(words[j].size()) - int(words[i].size()), int(words[i].size())));                } else {                    palidromeFlag = isPalidrome(words[i].substr(int(words[j].size()), int(words[i].size()) - int(words[j].size())));                    reverseFlag = isReverse(words[i].substr(0, int(words[j].size())), words[j]);                }                if (palidromeFlag && reverseFlag) {                    vector<int> singleResult = {i, j};                    resultVec.push_back(singleResult);                }            }        }        return resultVec;    }private:    bool isPalidrome(string str) {        int midInd = int(str.size() - 1) / 2;        int leftInd = int(str.size()) % 2 == 0?midInd:midInd-1;        int rightInd = midInd + 1;        while (leftInd >= 0 && rightInd < str.size()) {            if (str[leftInd] != str[rightInd]) {                return false;            }            leftInd--;            rightInd++;        }        return true;    }    bool isReverse(string leftStr, string rightStr) {        int strSize = int(leftStr.size());        for (int i = 0; i < strSize; i++) {            if (leftStr[i] != rightStr[strSize - 1 - i]) {                return false;            }        }        return true;    }};

但是提交上去遇到这个case的时候TLE了。改进思路,每次遍历的时候都要算一次isReverse,如果用一个哈希表存放candidates的反转字符串,比对的时候直接访问哈希表就可以了,用空间换时间。而且这样的话就不需要O(N^2)的遍历,只需要O(N)遍历的基础上遍历所有可能反转字符串。要注意空字符串的问题

class Solution {public:    vector<vector<int>> palindromePairs(vector<string>& words) {        unordered_map<string, int> hashTable;        for (int i = 0; i < words.size(); i++) {            string reverseStr = words[i];            reverse(reverseStr.begin(), reverseStr.end());            hashTable[reverseStr] = i;        }        vector<vector<int>> resultVec;        for (int i = 0; i < words.size(); i++) {            if (words[i].size() == 0) {                for (int j = 0; j < words.size(); j++) {                    if (j != i && isPalidrome(words[j])) {                        resultVec.push_back({i, j});                    }                }            }            for (int j = 0; j < words[i].size(); j++) {                string leftStr = words[i].substr(0, j), rightStr = words[i].substr(j, words[i].size() - j);                //分为在左拼接,在右拼接,这样就不用O(N^2)遍历                //在右拼接,还要考虑到candidate本身就是回文串的情况,加多一个判断条件                if (isPalidrome(rightStr) && hashTable.find(leftStr) != hashTable.end() && hashTable[leftStr] != i) {                    resultVec.push_back({i, hashTable[leftStr]});                }                //在左拼接                if (isPalidrome(leftStr) && hashTable.find(rightStr) != hashTable.end() && hashTable[rightStr] != i) {                    resultVec.push_back({hashTable[rightStr], i});                }            }        }        return resultVec;    }private:    bool isPalidrome(string str) {        int midInd = int(str.size() - 1) / 2;        int leftInd = int(str.size()) % 2 == 0?midInd:midInd-1;        int rightInd = midInd + 1;        while (leftInd >= 0 && rightInd < str.size()) {            if (str[leftInd] != str[rightInd]) {                return false;            }            leftInd--;            rightInd++;        }        return true;    }};
据说还有就TRIE的做法。

0 0
原创粉丝点击