記事ディレクトリ
件名:336。回文ペア
異なる単語のグループを指定して、リスト内の2つの単語、words [i] + words [j]をパリンドロームにスプライスできるように、すべての異なるインデックスペア(i、j)を見つけます。
例1:
输入:["abcd","dcba","lls","s","sssll"]
输出:[[0,1],[1,0],[3,2],[2,4]]
解释:可拼接成的回文串为 ["dcbaabcd","abcddcba","slls","llssssll"]
例2:
输入:["bat","tab","cat"]
输出:[[0,1],[1,0]]
解释:可拼接成的回文串为 ["battab","tabbat"]
ソース:LeetCode(LeetCode)
リンク:https ://leetcode-cn.com/problems/palindrome-pairs
著作権はLeetCode が所有しています。商用転載については、正式な許可書にご連絡ください。非商用転載については、出典を明記してください。
基本的な考え方:回文を構成する2つの弦の特徴から始める
暴力的な方法はこの質問には使えません。
回文を構成する2つの部分文字列の特性:
- 文字列自体は回文であるため、空の文字列と2つの回文ペアを形成できます。
- 文字列シーケンスの文字列の逆の文字列があり、2つの文字列を結合して回文文字列を形成できます
- 文字列の最初の部分または後半の部分は回文文字列であり、他の部分の逆の文字列は文字列シーケンスに含まれます。2つの文字列を連結すると、文字列を形成できます
class Solution {
public:
unordered_map<string, int> m;
vector<vector<int>> palindromePairs(vector<string>& words) {
for(int i = 0; i < words.size(); ++i){
string s = words[i];
reverse(s.begin(), s.end());
m[s] = i;
}
vector<vector<int>> res;
for(int i = 0; i < words.size(); ++i){
if(words[i] == "")
continue;
if(m.count(words[i]) && m[words[i]] != i){
res.push_back({
i, m[words[i]]});
}
for(int j = 0; j < words[i].size(); ++j){
if(isPalindrome(words[i], 0, j)){
string temp = words[i].substr(j + 1, words[i].size() - j - 1);
if(m.count(temp)){
res.push_back({
m[temp], i});
}
}
if(isPalindrome(words[i], j, words[i].size() - 1)){
string temp = words[i].substr(0, j);
if(m.count(temp)){
res.push_back({
i, m[temp]});
}
}
}
}
return res;
}
bool isPalindrome(string s, int l, int r){
while(l < r){
if(s[l++] != s[r--])
return false;
}
return true;
}
};