LeetCode: Palindrome Pairs

来源:互联网 发布:爬虫软件有哪些 编辑:程序博客网 时间:2024/04/30 21:26

这个问题需要我们判断给定的一系列字符串中,能够构成回文字符串的字符串对有哪些?那么一个经典思路就是采用暴力求解,两个循环撸出来。

暴力求解

vector<vector<int>> palindromePairs(vector<string>& words) {    vector<vector<int>> result;    for (int i = 0; i<words.size(); i++){        for (int j = 0; j < words.size(); j++){            if (j != i){                string tail = words[j];                string head = words[i];                head += tail;                //  Determine whether string is palindrome                int found = 1;                if (head.empty())                    found = -1;                else{                    int len = head.length();                    for (int k = 0; k < len / 2; k++){                        if (head[k] != head[len - k - 1]){                            found = 0;                            break;                        }                    }                }                //  Store the palindrome pair                if (found == 1){                    result.push_back({ i, j });                }            }        }    }    return result;}

不过这题难就难在会超时,所以一定要修改。一个新的思路是,对每个字符串与比它短的字符串进行首尾匹配,比它长的字符串可以进行一个交换,之后的思路还是一样的。一个例子,字符串“bbbbbbbbcasfsdfsd”,与比它短的字符串“dsf”匹配,匹配成功后对剩下的字符串“bbbbbbbbcasfsd”进行回文判断;当满足上面两个条件时,则返回回文对。

修改后的算法

vector<vector<int>> palindromePairs(vector<string>& words) {    vector<vector<int>> result;    vector<int> wordLength;    unordered_map<string, int> map;    for (int i = 0; i < words.size(); i++){        map[words[i]] = i;        wordLength.push_back(words[i].length());    }    for (int i = 0; i < words.size(); i++){        string str = words[i];        int length = str.length();        reverse(str.begin(), str.end());        //  Find words of same length        if (map.count(str) && map[str] != i)            result.push_back({ i, map[str] });        //  Deal with words of different length        sort(wordLength.begin(), wordLength.end());        vector<int>::iterator iter = find(wordLength.begin(), wordLength.end(), length);        for (vector<int>::iterator it = wordLength.begin(); it != iter; it++){            int shorterLength = *it;            //  Forward matching            if (map.count(str.substr(0, shorterLength)))                if (isValid(str, shorterLength, length - 1))                    result.push_back({ map[str.substr(0, shorterLength)], i });            //  Backward matching            if (map.count(str.substr(length - shorterLength)))                if (isValid(str, 0, length - shorterLength - 1))                    result.push_back({ i, map[str.substr(length - shorterLength)] });        }    }    return result;}

这里可能用到了一个unordered_map,主要是解决题目假设:自身与自身不能形成回文对。但是很不幸,这个还是超时了…….0.0。后来网上看到了一个别人的解法,思路类似,但是由于它在存储短的字符串的长度时用了set(自动排序且自动去重),这就大大加快了算法计算速度。(我还是太年轻了= =)

最终提交版本

vector<vector<int>> palindromePairs(vector<string>& words) {    vector<vector<int>> res;    unordered_map<string, int> m;    set<int> s;    for (int i = 0; i < words.size(); ++i) {        m[words[i]] = i;        s.insert(words[i].size());    }    for (int i = 0; i < words.size(); ++i) {        string t = words[i];        int len = t.size();        reverse(t.begin(), t.end());        if (m.count(t) && m[t] != i) {            res.push_back({ i, m[t] });        }        auto a = s.find(len);        for (auto it = s.begin(); it != a; ++it) {             int d = *it;            if (isValid(t, 0, len - d - 1) && m.count(t.substr(len - d))) {                res.push_back({ i, m[t.substr(len - d)] });            }            if (isValid(t, d, len - 1) && m.count(t.substr(0, d))) {                res.push_back({ m[t.substr(0, d)], i });            }        }    }    return res;}
0 0
原创粉丝点击