题目链接:
https://leetcode-cn.com/problems/pattern-matching-lcci/
难度:中等
面试题 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="",反之也符合规则
提示:
0 <= len(pattern) <= 1000
0 <= len(value) <= 1000
你可以假设pattern只包含字母"a"和"b",
value仅包含小写字母。
呵呵,重新定义了我对中等难度的认知 ,一个字 不会
首先我开始的想法是 枚举 , 但是并没有想到是要对字符的长度进行枚举, 是对 ab的每一种可能进行枚举,但是这样太复杂了!!!但是又没想到其他的方法
然后看了看 解析 对啊 对 ab 的长度进行 枚举不就可以了吗!!!
- 不考虑极端情况(value和pattern空)
要判断是否匹配 对a,b的长度进行枚举。那么这样 思路就很清晰了。
value和pattern的是已知的,通过遍历pattern获取a b 的个数 记为 acount和bcount(bcount=value.size()-acount)
现在对 acount 进行枚举,在内部在对pattern进行遍历,那么就可以很轻松的获取 a和b值分别是什么。
(如: value=”aaaddd“ pattern=”ab“ 此时 acount = 2
那么 a=”aa“)
注意 还有一个等量关系需要注意 a的长度*acount+b的长度*bcount的长度=value的长度
此时 只需要对value 按照 ab已经获取的值进行遍历检测即可
还要注意 a b有可能只存在一个 且 a!=b - 极端情况
vaule为空 pattern 为空 或 只有一个字母 返回true
pattern为空 value为空 返回true
class Solution {
public:
bool patternMatching(string pattern, string value) {
// lp为pattern的长度
int lp = pattern.size();
// a的个数
int acount = 0;
for (char ch : pattern) {
if ( ch == 'a')
acount++;
}
// b的个数
int bcount = lp - acount;
// 保证a的值必大于0
// 交换 a b (对结果无影响)
if (acount < bcount) {
swap(acount, bcount);
for (char &ch : pattern) {
ch = (ch == 'a' ? 'b' : 'a');
}
}
// value为空
// (pattern 为空或只有一个字母) 等价于 bcount == 0
if (value.empty()) {
return bcount == 0;
}
// 运行到这 说明value不为空 则必为false
if (pattern.empty()) {
return false;
}
// 对 a的长队进行枚举 la为a的长度
for (int la = 0; acount * la <= value.size(); ++la) {
// tmp=bcount*lb
int tmp = value.size() - acount * la;
// 对应两种情况 b个数为0 value皆由a提供
// 存在b 且b的长度为自然数
if ((tmp == 0 && bcount == 0) || (bcount != 0 && tmp % bcount == 0)) {
int lb = bcount == 0 ? 0 : tmp / bcount;
int pos = 0;
string stra = "";
string strb = "";
bool istrue = true;
for (char ch : pattern) {
if (ch == 'a') {
string sub = value.substr(pos, la);
// 是否为第一次
if (stra.empty()) {
stra = move(sub);
}
// a值是否相同
else if (stra != sub) {
istrue = false;
break;
}
pos += la;
}
else {
string sub = value.substr(pos, lb);
if (strb.empty()) {
strb = move(sub);
}
else if (strb != sub) {
istrue = false;
break;
}
pos += lb;
}
}
if (istrue && stra != strb) {
return true;
}
}
}
return false;
}
};