当前位置:首页 > 力扣 > 力扣面试16.18题解析:模式匹配问题的算法优化与实现(动态规划+字符串匹配)

力扣面试16.18题解析:模式匹配问题的算法优化与实现(动态规划+字符串匹配)

3个月前 (07-07)

力扣面试16.18题解析:模式匹配问题的算法优化与实现(动态规划+字符串匹配) 模式匹配 动态规划 字符串匹配 算法优化 力扣面试题 第1张

一、题目解读

力扣面试16.18题要求判断字符串value是否可通过替换模式串pattern中的字符"a"和"b"(任意非空子串)进行匹配。例如,模式"aab"可匹配"xxxy",但无法匹配"xyx"。题目需高效算法判断匹配关系,涉及字符串处理动态规划思想。

二、解题思路

采用统计+枚举策略:

1. 统计字符数量:计算pattern中a、b出现次数,确保a为多数字符(通过交换优化后续处理)。

2. 空值处理:若value为空,仅当pattern全a或全b时才匹配。

3. 枚举a的长度:遍历a的可能子串长度,计算剩余字符是否可被b均分。

4. 匹配验证:通过滑动窗口逐字符匹配,确保同一字母对应的子串一致。

三、解题步骤

1. 预处理:统计a、b数量并交换,使a占多数,减少分支讨论。

2. 处理空值:快速判断value为空的特例。

3. 枚举长度:从0到value长度除以a次数,计算b子串长度(或0)。

4. 匹配验证:使用双指针分别构建value_a和value_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'; // 交换a和b
            }
        }
        
        // 处理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; // 记录第一个a对应的子串
                        } 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;
                    }
                }
                if (match && pos == value.size()) return true; // 完全匹配成功
            }
        }
        return false;
    }
};

五、总结

该解法通过统计与枚举结合,巧妙利用字符数量关系减少搜索空间。关键点在于:

1. 交换a、b确保主字符更易处理;

2. 空值特判避免后续逻辑复杂;

3. 滑动窗口匹配子串的一致性。

此思路对字符串匹配类问题具有通用性,体现了动态规划中“状态压缩”与“边界优化”的精髓。

原创内容 转载请注明出处

分享给朋友:

相关文章

【动态规划入门】力扣509题:斐波那契数列的经典解法与优化思路

【动态规划入门】力扣509题:斐波那契数列的经典解法与优化思路

题目解读‌斐波那契数列是一个经典的数学问题,在计算机科学中常被用作算法教学的入门案例。这个神奇的数列从0和1开始,后续每个数字都是前两个数字之和。题目要求我们计算第n个斐波那契数,看似简单的问题背后却...

NOIP 2008火柴棒等式题解(C++代码实现)  动态规划与枚举算法详解

NOIP 2008火柴棒等式题解(C++代码实现) 动态规划与枚举算法详解

一、题目解读火柴棒等式问题(NOIP 2008,洛谷P1149)要求使用给定数量的火柴棒,构造形如 A + B = C 的等式,其中A、B、C均为整数,且火柴棒总数恰好等于输入值。需统计符合条件的等式...

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

洛谷P4999题解析:动态规划求解数字拆分与求和问题(附代码)

一、题目解读洛谷P4999题要求处理给定区间 [L, R] 内数字的拆分与求和问题。每个数字需拆分为其各位数字之和,并计算区间内所有数字之和的累加结果。题目需考虑大数情况,并采用取模运算(MOD=1e...

牛客25461题解析:花园喷泉距离优化算法(动态规划+后缀数组解法)

牛客25461题解析:花园喷泉距离优化算法(动态规划+后缀数组解法)

一、题目解读牛客25461题要求计算一个花园中n朵花到两个喷泉的最小距离平方和。用户需输入喷泉坐标(x1,y1)和(x2,y2),以及n朵花的坐标(x,y),通过合理分配每朵花到两个喷泉的距离,使总距...

洛谷P10472题解:利用栈求解最长有效括号

洛谷P10472题解:利用栈求解最长有效括号

一、题目解读洛谷P10472题要求计算给定字符串中最长有效括号的长度。有效括号指括号成对匹配(如"()[]{}"),子串需连续且内部嵌套正确。题目核心在于判断括号匹配的连续性,并找...

【蓝桥杯国赛A组】冰山体积计算:动态规划与map统计的解题方案(洛谷P8767)

【蓝桥杯国赛A组】冰山体积计算:动态规划与map统计的解题方案(洛谷P8767)

一、题目解读本题为2021年蓝桥杯国赛A组题目“冰山”(洛谷P8767),要求处理冰山在融化与新生成过程中的体积变化。每日存在两种操作:冰山体积按固定值x融化(体积不足x的部分视为完全融化),以及新增...

发表评论

访客

看不清,换一张

◎欢迎参与讨论,请在这里发表您的看法和观点。