(16) 面试题 16.18. 模式匹配

题目链接:
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 的长度进行 枚举不就可以了吗!!!

  1. 不考虑极端情况(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
  2. 极端情况
    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;
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值