面试题 16.18. 模式匹配
你有两个字符串,即pattern
和value
。 pattern
字符串由字母"a"
和"b
"组成,用于描述字符串中的模式。例如,字符串"catcatgocatgo"
匹配模式"aabab"
(其中"cat
"是"a"
,"go"
是"b"
),该字符串也匹配像"a"
、"ab"
和"b"
这样的模式。但需注意"a"
和"b"
不能同时表示相同的字符串。编写一个方法判断value
字符串是否匹配pattern
字符串。
示例 1:
输入: pattern = "abba", value = "dogcatcatdog"
输出: true
示例 2:
输入: pattern = "abba", value = "dogcatcatfish"
输出: false
示例 3:
输入: pattern = "aaaa", value = "dogcatcatdog"
输出: false
示例 4:
输入: pattern = "abba", value = "dogdogdogdog"
输出: true
解释: "a"="dogdog",b="",反之也符合规则
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/pattern-matching-lcci
思路
本题的要求是两个字符串是否能对应上,分清况讨论:pattern
要么为空,要么是ab
组合或者全a
,全b
- 为空,
value
也必须是空值,否则错误; - 全
a
或者全b
,value
只能有一种单词,但可以有很多个,这一单词的数量取决于a
或b
的个数,所以我们可以统计a
或b
个数,将value
按照其个数平分,判断每一个单词是否相同,如果出现不同,即为错误 ab
组合,思路同上一种情况一致,分别统计a
和b
的个数,如何对应上value
?
首先长度对应上,假设a
对应字符串的长度为len_a
,b
对应的字符串的长度即为(value.size()-count_a*len_a)/count_b
,如果不能够整除,说明肯定存在不同单词。此时可能count_b==0
,那么value.size()-len_a*count_a==0
。此时,len_a
有不同取值,但是count_a*len_a<=value.size()
,枚举取值即可。
代码
class Solution {
public:
bool patternMatching(string pattern, string value) {
//pattern中a\b的数量
int count_a = 0,count_b = 0;
for (auto& ch:pattern){
if (ch == 'a')
++count_a;
else
++count_b;
}
//判断对应哪种情况,如果value为空,个数少的肯定为0,此时pattern只有一个字符或者空,可以对应上value为空。所以可以始终让b的个数为0。交换字符
if (count_a < count_b){
swap(count_a,count_b);
for (auto& ch:pattern){
ch = (ch == 'a' ? 'b':'a');
}
}
//如果value为空,pattern只只有一个字符或者为空即为正确
if (value.empty())
return count_b == 0;
//如果pattern为空,value不为空,结果错误
if (pattern.empty())
return false;
//枚举len_a的取值
for (int len_a = 0;len_a * count_a <= value.size();++len_a){
int rest = value.size() - len_a * count_a;
if ((count_b == 0 && rest == 0) || (count_b != 0&&rest % count_b == 0)){
//求出len_b
int len_b = (count_b == 0?0:rest / count_b);
//定位指针,随着len_a或len_b移动
int pos = 0;
//字符a和b对应的字符串
string value_a,value_b;
bool correct = true;
for (auto& ch:pattern){
if (ch == 'a'){
string sub = value.substr(pos,len_a);
if (!value_a.size())
value_a = move(sub);
else if (value_a != sub){
correct = false;
break;
}
pos += len_a;
}else{
string sub = value.substr(pos,len_b);
if (!value_b.size())
value_b = sub;
else if (value_b != sub){
correct = false;
break;
}
pos += len_b;
}
}
if (correct && value_a != value_b)
return true;
}
}
return false;
}
};