leetcode刷题-面试题 16.18. 模式匹配

面试题 16.18. 模式匹配

你有两个字符串,即patternvaluepattern字符串由字母"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或者全bvalue只能有一种单词,但可以有很多个,这一单词的数量取决于ab的个数,所以我们可以统计ab个数,将value按照其个数平分,判断每一个单词是否相同,如果出现不同,即为错误
  • ab组合,思路同上一种情况一致,分别统计ab的个数,如何对应上value
    首先长度对应上,假设a对应字符串的长度为len_ab对应的字符串的长度即为(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;
    }
};
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值