class Solution {
public:
vector<string> findAndReplacePattern(vector<string>& words, string p) {
vector<string> ans;
for(auto &w:words){
if(match(w,p))
ans.push_back(w);
}
return ans;
}
bool match(string &w1,string &w2){
unordered_map<char,char>w1_to_w2,w2_to_w1;
for( i=0;i<w1.size();i++)
if( (w1_to_w2.count(w1[i]) && w1_to_w2[w1[i]] != w2[i]) ||
(w2_to_w1.count(w2[i]) && w2_to_w1[w2[i]] != w1[i]) )
return false;
else
w1_to_w2[w1[i]] = w2[i],
w2_to_w1[w2[i]] = w1[i];
return true;
}
};
输入:
words = ["abc","deq","me","aqq","dkd","ccc"]
pattern = "abb">
输出:
["me","aqq"]
说明:
"me"匹配模式,因为存在排列{a -> m, b -> e, ...}
"ccc"不匹配模式,因为{a -> c, b -> c, ...}
不是排列,因为a
和b
映射到同一个字母。
这是如何工作的,尤其是count
?请逐步解释。
findAndReplacePattern(words, p)
只是为words
中的每个单词调用match(
单词, p)
- 如果它们匹配,则单词将附加到ans
,稍后返回。
在match(w1, w2)
中,w1_to_w2
和w2_to_w1
最初是空的,i
沿着两个字符串计数(假设它们的长度相同 - 通常是一个危险的假设,可能导致程序崩溃)。
在第一次迭代中,当i
为 0 时,.count(...)
调用返回 0,因为unordered_maps中没有任何内容,因此函数不会返回。 相反,if 计算else
子句,该子句记录:
w1
中的第一个字母 -w1[0]
- 对应于w2
中的第一个字母,通过执行赋值w1_to_w2[w1[i]] = w2[i]
,并且w2
中的第一个字母 -w2[0]
- 对应于w1
中的第一个字母,通过执行赋值w2_to_w1[w2[i]] = w1[i]
。
当它沿着单词中的其余字母前进时......
w1_to_w2.count(w1[i]) && w1_to_w2[w1[i]] != w2[i]
。是说,如果我们已经在w1
中看到过与w1[i]
相同的字母,并且w2
的字母对应于之前(即w1_to_w2[w1[i]]
) 不是它现在对应的字母(即w2[i]
),这将是返回false
的原因之一,或者...
w2_to_w1.count(w2[i]) && w2_to_w1[w2[i]] != w1[i]
。如果我们已经在w2
中看到与w2[i]
相同的字母,并且w1
的字母对应于之前(即w2_to_w1[w2[i]]
) 与现在对应的字母不同(即w1[i]
),这将是返回false
的另一个原因。