题目描述
描述:你有两个字符串,即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="",反之也符合规则
提示:
1 <= len(pattern) <= 1000
0 <= len(value) <= 1000
你可以假设pattern只包含字母"a"和"b",value仅包含小写字母。
解题思路
思路1:最直观的想法是,回溯。首先统计pattern中a的数量numa和b的数量numb,再使用dfs(pindex,vindex,pattern,value)进行pattern和value的模式匹配。在匹配过程中,使用指针pindex表示pattern当前匹配位置,使用指针vindex表示value当前匹配位置。当pindex对应元素为a时:如果a当前已经被赋值,则判断合法性后再进行下一个位置的匹配;反之如果a当前未被赋值,则以value为基础遍历a的长度[0,value.size()],同时判断合法性以及相应处理后再进行下一个位置的匹配。b同a。
//表示pattern中字符a的数量
int numa=0;
//表示pattern中字符b的数量
int numb=0;
//a和b初始均为空格表示未赋值
string a=" ";
string b=" ";
//flag表示是否匹配
bool flag=false;
//pindex表示当前pattern中的字符序号
//vindex表示当前value中的字符序号
void dfs(int pindex,int vindex,string pattern,string value)
{
if(flag)
return;
//a和b均已赋值且长度不匹配
if(a!=" "&&b!=" "&&numa*a.size()+numb*b.size()!=value.size())
return;
//a已赋值但是b未赋值且长度不匹配
if(a!=" "&&numb>0&&b==" "&&((value.size()-numa*a.size())%numb!=0))
return;
//a未赋值但是b已赋值且长度不匹配
if(a==" "&&numa>0&&b!=" "&&(value.size()-numb*b.size())%numa!=0)
return;
//pattern和value均已到达尾部标记成功处理完成
if(pindex==pattern.size()&&vindex==value.size())
{
flag=true;
return;
}
//pattern和value已经越界
if(pindex>pattern.size()||vindex>value.size())
return;
//开始进入正式的匹配过程
if(pattern[pindex]=='a')
{
//a已经被赋值则直接处理
if(a!=" ")
{
//如果value越界或者value接下来部分与a不同
if(vindex+a.size()>value.size()||value.substr(vindex,a.size())!=a)
return;
//反之继续处理
else
dfs(pindex+1,vindex+a.size(),pattern,value);
}
//a未被赋值则以value为基础挨个枚举a的长度
else
{
//a的长度范围是0~value.size()
for(int i=0;i<=value.size();i++)
{
if(vindex+i>value.size())
return;
//pattern第一个是a则b也未被赋值
if(pindex==0)
b=" ";
a=value.substr(vindex,i);
dfs(pindex+1,vindex+i,pattern,value);
}
}
}
//开始进入正式的匹配过程
if(pattern[pindex]=='b')
{
//b已经被赋值则直接处理
if(b!=" ")
{
//如果value越界或者value接下来部分与b不同 if(vindex+b.size()>value.size()||value.substr(vindex,b.size())!=b)
return;
//反之继续处理
else
dfs(pindex+1,vindex+b.size(),pattern,value);
}
//b未被赋值则以value为基础挨个枚举b的长度
else
{
//b的长度范围是0~value.size()
for(int i=0;i<=value.size();i++)
{
if(vindex+i>value.size())
return;
//pattern第一个是a则b也未被赋值
if(pindex==0)
a=" ";
b=value.substr(vindex,i);
//a和b不能相同
if(a==b)
continue;
dfs(pindex+1,vindex+i,pattern,value);
}
}
}
}
bool patternMatching(string pattern, string value)
{
for(int i=0;i<pattern.size();i++)
{
if(pattern[i]=='a')
numa++;
if(pattern[i]=='b')
numb++;
}
dfs(0,0,pattern,value);
return flag;
}
总结:万一pattern中不止a和b又该如何处理呢?