当前位置:首页 > 力扣 > 力扣3407题解:利用星号通配符优化字符串匹配

力扣3407题解:利用星号通配符优化字符串匹配

7个月前 (08-03)

力扣3407题解:利用星号通配符优化字符串匹配 力扣题解 字符串匹配 C++ 分治策略 字符串 第1张

一、题目解读

力扣3407题要求判断给定字符串s是否匹配模式串p,其中p允许包含通配符“”(匹配任意字符序列)。题目核心在于处理星号的灵活匹配规则,需考虑前后缀的组合匹配情况,同时避免无效匹配位置。理解“”的任意扩展特性是解题的关键。

二、解题思路

采用“分治+定位”策略:

1. 定位p中星号位置,将模式分为前后缀;

2. 优先匹配前缀在s中的首次出现位置;

3. 利用后缀在剩余子串中的逆序查找,确保匹配顺序正确;

4. 通过边界条件(如空串、仅星号)及位置验证规避无效情况。

此思路巧妙利用字符串查找函数(find/rfind),避免暴力匹配,提升效率。

三、解题步骤

1. 定位星号,分割模式:通过find获取星号索引,将p分为前缀(左侧)和后缀(右侧)。

2. 处理特殊边界:

○ 若p="*",直接返回true(空串匹配);

○ 若s为空,仅当p前后缀均为空才匹配。

3. 前缀匹配定位:在s中查找前缀首次出现位置(find),若不存在则失败。

4. 后缀逆序匹配:从匹配点后开始,逆序查找后缀(rfind),确保后缀在剩余部分末尾。

5. 验证位置合法性:检查后缀匹配是否在前缀之后且不越界,避免如“*ab”匹配“abab”的误判。

四、代码与注释

class Solution {  
public:  
    bool hasMatch(string s, string p) {  
        // 1. 定位星号,分割模式  
        size_t star_pos = p.find('*');  
        string prefix = p.substr(0, star_pos); // 星号前部分  
        string suffix = p.substr(star_pos + 1); // 星号后部分  
        
        // 2. 特殊边界处理  
        if (prefix.empty() && suffix.empty()) return true; // p="*"  
        if (s.empty()) return prefix.empty() && suffix.empty();  
        
        // 3. 查找前缀在s中的位置  
        size_t prefix_match = s.find(prefix);  
        if (prefix_match == string::npos) return false;  
        
        // 4. 剩余部分逆序查后缀  
        size_t start_search = prefix_match + prefix.length();  
        if (start_search > s.length()) return suffix.empty();  
        size_t suffix_match = s.rfind(suffix);  
        if (suffix_match == string::npos) return false;  
        
        // 5. 验证位置合法性  
        return (suffix_match >= start_search) &&  
               (suffix_match + suffix.length() <= s.length());  
    }  
};

通过精简的逻辑与原生函数(find/rfind)实现高效匹配,避免递归或复杂循环。

五、总结

本解法通过“分治定位+边界优化”思路,将星号匹配转化为前后缀的独立查找,结合位置验证确保匹配顺序正确。时间复杂度O(m+n),适用于中等规模字符串场景。在工程应用中,该策略可扩展至文件检索、文本过滤等需通配符匹配的场景,兼具效率与实用性。

原创内容 转载请注明出处

分享给朋友:

相关文章

力扣35:二分法在搜索插入位置中的运用

力扣35:二分法在搜索插入位置中的运用

有序数组的定位在一个严格递增的数字序列中,每个元素都有其确定的位置。当新元素试图加入时,我们需要回答两个问题:它是否已经存在?如果不存在,它应该插入在哪里?这道题要求我们在O(log n)时间内完成这...

力扣第71题:用栈轻松解决Unix路径简化问题

力扣第71题:用栈轻松解决Unix路径简化问题

题目解读:在Unix风格的文件系统中,我们经常需要处理各种复杂的路径表示。给定一个绝对路径字符串,我们需要将其转换为最简化的规范路径。规范路径要求:路径始终以斜杠'/'开头;两个目录名...

力扣965题深度解析:单值二叉树的判断技巧

力扣965题深度解析:单值二叉树的判断技巧

重新解读题目 判断一棵二叉树是否为“单值二叉树”,即所有节点的值是否完全相同。题目看似简单,实则考验对树结构递归特性的理解。若一棵树的所有节点值相同,其必然满足:根节点与左右子树的值一致,且...

手搓顺序表类代码注释与详解:从零实现动态数组(新手教程)

一、简介和特点顺序表(Sequential List)是数据结构中基础的一种线性表,其特点是将数据元素存储在连续的内存空间中。通过数组实现,支持随机访问(即通过索引直接访问元素),适用于频繁随机读取的...

牛客14496题解:括号最大深度问题(栈思想与代码优化)

牛客14496题解:括号最大深度问题(栈思想与代码优化)

一、题目解读牛客14496题要求计算给定括号字符串中的最大深度。例如,对于字符串 "(()())",最大深度为2。题目考察对括号嵌套结构的理解,以及如何通过编程找到最深嵌套层次。二...

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

力扣3112题解法:带时间限制的最短路径问题解析(C++代码)

一、题目解读力扣3112题要求解决带时间限制的最短路径问题:给定一个有向图,节点具有消失时间,需计算从起点到各节点的最短路径,且路径总时间不能超过节点的消失时间。题目难点在于需在传统最短路径算法(如D...

发表评论

访客

看不清,换一张

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