返回
C/C++ 1408. 数组中的字符串匹配:优化空间,高效搜索!
后端
2023-11-05 16:21:14
题目
给定一个字符串数组 words
和一个字符串 pattern
,找出 words
中的所有字符串 word
,使得 word
与 pattern
匹配。
匹配规则定义如下 :
pattern
和word
都由小写英文字母组成。pattern
的长度与word
的长度相等。pattern
可以包含一个或多个 '' 字符,'' 可以匹配任意字符。
示例 1 :
输入:words = ["abc","deq","mee","aqq","dkd","ccc"], pattern = "abb"
输出:["mee","aqq"]
解释:
"mee" 与 "abb" 匹配,因为 '*' 可以匹配 'e'。
"aqq" 与 "abb" 匹配,因为 '*' 可以匹配 'q'。
其他字符串不匹配 "abb"。
示例 2 :
输入:words = ["a","b","c"], pattern = "a*b*"
输出:["a","b","c"]
解释:
"*" 可以匹配任何字符,因此 "a*b*" 可以匹配 "a"、"b" 和 "c"。
提示 :
1 <= words.length <= 50
1 <= words[i].length <= 50
1 <= pattern.length <= 50
words
和pattern
都由小写英文字母组成pattern
可以包含一个或多个 '' 字符
题目整理
- 输入 :字符串数组
words
和字符串pattern
- 输出 :所有与
pattern
匹配的字符串word
,其中 '*' 可以匹配任意字符 - 匹配规则 :
pattern
和word
都由小写英文字母组成pattern
的长度与word
的长度相等pattern
可以包含一个或多个 '' 字符,'' 可以匹配任意字符
题目的解题思路
这道题目本质上是一个字符串匹配的问题。我们可以使用 KMP 算法或 Trie 树来解决。KMP 算法的时间复杂度为 O(n+m)
,其中 n
是 pattern
的长度,m
是 words
中所有字符串的总长度。Trie 树的时间复杂度为 O(n+m)
,其中 n
是 pattern
的长度,m
是 words
中所有字符串的总长度。
由于 KMP 算法和 Trie 树都是比较复杂的算法,因此我们这里使用一种更简单的方法来解决这个问题。
我们可以将 pattern
中的所有字符分为两类:
- 常规字符:即不是 '*' 的字符
- 通配符字符:即 '*' 字符
对于常规字符,我们可以直接比较 pattern
和 word
中对应位置的字符是否相等。对于通配符字符,我们可以使用以下规则来匹配:
- 通配符字符可以匹配任意字符
- 通配符字符可以匹配零个或多个字符
我们可以使用回溯法来枚举所有可能的匹配方案。对于每一个通配符字符,我们可以尝试匹配零个或多个字符。如果匹配成功,我们就继续匹配下一个字符。如果匹配失败,我们就回溯到上一个通配符字符,尝试匹配另一个方案。
使用这种方法,我们可以找到所有与 pattern
匹配的字符串 word
。
具体的实现和代码
class Solution {
public:
vector<string> findAndReplacePattern(vector<string>& words, string pattern) {
vector<string> result;
for (string& word : words) {
if (isMatch(word, pattern)) {
result.push_back(word);
}
}
return result;
}
private:
bool isMatch(string word, string pattern) {
int n = word.size();
int m = pattern.size();
if (n != m) {
return false;
}
unordered_map<char, char> patternToWord;
unordered_map<char, char> wordToPattern;
for (int i = 0; i < n; i++) {
char c1 = pattern[i];
char c2 = word[i];
if (patternToWord.count(c1) == 0 && wordToPattern.count(c2) == 0) {
patternToWord[c1] = c2;
wordToPattern[c2] = c1;
} else if (patternToWord[c1] != c2 || wordToPattern[c2] != c1) {
return false;
}
}
return true;
}
};
总结
这道题目考察的是字符串匹配的基本功。我们可以使用 KMP 算法或 Trie 树来解决这个问题,也可以使用回溯法来枚举所有可能的匹配方案。只要我们能够正确地理解题意,并熟练掌握字符串匹配的算法,我们就可以轻松地解决这个问题。