力扣面试16.18题解:模式匹配问题的完整实现指南
一、问题描述
给定一个模式字符串pattern和一个值字符串value,判断value是否能够匹配pattern。模式由字母a和b组成,表示一种字符串模式,其中a和b分别表示不同的子字符串。
二、算法核心思想
本解决方案采用枚举和验证的方法:
统计模式中a和b的出现次数
确保a是出现次数较多的字符以简化处理
处理特殊边界情况(空字符串)
枚举a可能的长度并计算对应的b长度
验证每种可能的长度组合是否匹配
三、完整代码实现(带详细注释)
class Solution { public: bool patternMatching(string pattern, string value) { // 统计pattern中a和b的数量 int count_a = 0, count_b = 0; for (char c : pattern) { if (c == 'a') count_a++; else count_b++; } // 确保a是出现次数较多的字符,简化后续处理 if (count_a < count_b) { swap(count_a, count_b); for (char& c : pattern) { c = (c == 'a') ? 'b' : 'a'; } } // 处理value为空的情况 if (value.empty()) { return count_b == 0; // 只有全a或全b的模式可以匹配空字符串 } // 枚举a可能的长度 for (int len_a = 0; len_a <= value.size() / count_a; ++len_a) { int remaining = value.size() - count_a * len_a; // 检查b的长度是否有效 if ((count_b == 0 && remaining == 0) || (count_b != 0 && remaining % count_b == 0)) { int len_b = (count_b == 0) ? 0 : remaining / count_b; // 尝试匹配 int pos = 0; string value_a, value_b; bool match = true; for (char c : pattern) { if (c == 'a') { string sub = value.substr(pos, len_a); if (value_a.empty()) { value_a = sub; } else if (value_a != sub) { match = false; break; } pos += len_a; } else { string sub = value.substr(pos, len_b); if (value_b.empty()) { value_b = sub; } else if (value_b != sub) { match = false; break; } pos += len_b; } } // 检查a和b不能表示相同字符串 if (match && value_a != value_b) { return true; } } } return false; } };
四、算法分步解析
统计阶段:
统计模式中a和b的出现次数
确保a是出现次数较多的字符
边界处理:
处理value为空字符串的特殊情况
枚举阶段:
枚举a可能的长度
计算对应的b长度
检查长度组合的有效性
验证阶段:
尝试每种可能的长度组合
验证是否匹配整个字符串
确保a和b表示不同的子字符串
五、常见误区与调试技巧
忘记处理模式全为a或全为b的情况
没有正确处理空字符串的情况
枚举长度时边界条件错误
忘记验证a和b不能表示相同字符串
六、扩展思考
原创内容 转载请注明出处