Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).不同于正则表达式中的*

*正则表达式的定义:

  • '.' Matches any single character.
  • '*' Matches zero or more of the preceding element.
The matching should cover the entire input string (not partial).The function prototype should be:
bool isMatch(const char *s, const char *p)Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "*") → true
isMatch("aa", "a*") → true
isMatch("ab", "?*") → true
isMatch("aab", "c*a*b") → false

思路I:当遇到*,有把*跳过,和继续保留*两种option=>带回溯的递归。其实也可称之为贪心法,贪心法则是每次都使*匹配尽可能少的字符。

class Solution {
public:bool isMatch(string s, string p) {return backTracking(s,p,0,0);}bool backTracking(string s, string p, int sp, int pp){//end conditionif(sp==s.length()){while(pp<p.length() &&p[pp]=='*' ){pp++;}if(pp == p.length()) return true;else return false;}if(pp==p.length()) return false;if(p[pp]=='*'){while(pp+1<p.length() && p[pp+1]=='*') pp++; //ignore the stars directly behind starif(backTracking(s,p,sp,pp+1)) return true; //* not repeatsreturn backTracking(s,p,sp+1,pp); //* repeats
        }else if(s[sp]==p[pp] || p[pp]=='?') return backTracking(s,p,sp+1,pp+1);else return false;}
};

时间复杂度:二叉recursion的高度是2n  所以O(2n)

Result: Time Limit Exceeded

思路II:依然是带回溯的递归,只是记录下*号位置,和匹配的字符数,那么等到某次*不匹配时可直接回到该位置。

class Solution {
public:bool isMatch(string s, string p) {star = false;return recursiveCheck(s,p,0,0);}bool recursiveCheck(const string &s, const string &p, int sIndex, int pIndex){if(sIndex >= s.length()){while(p[pIndex] == '*' && pIndex < p.length()) pIndex++; //s has went to end, check if the rest of p are all *return (pIndex==p.length());}if(pIndex >= p.length()){return checkStar(s,p);}switch(p[pIndex]) //p: pattern,在p中才可能出现?, *
        { case '?':return recursiveCheck(s, p, sIndex+1, pIndex+1);break;case '*': //如果当前为*, 那么可认为之前的字符都匹配上了,并且将p移动到 * 结束后的第一个字符star = true;  //p 每次指向的位置,要么是最开始,要么是 * 结束的第一个位置starIndex = pIndex;matchedIndex = sIndex-1;while(p[pIndex] == '*'&& pIndex < p.length()){pIndex++;} //忽略紧接在 *后面的* if(pIndex==p.length()) return true;//最后一位是*return recursiveCheck(s,p,sIndex,pIndex); //*匹配0个字符break;default:if(s[sIndex] != p[pIndex]) return checkStar(s, p);else return recursiveCheck(s, p, sIndex+1, pIndex+1);break;}}bool checkStar(const string &s, const string &p){if(!star) return false;else {int pIndex = starIndex+1;int sIndex = ++matchedIndex; //回溯,*d多匹配一个字符return recursiveCheck(s, p, sIndex, pIndex);}}
private:int starIndex;int matchedIndex;bool star;
};

Result: Approved.

思路III:使用dp。dp[i][j]表示从字符串到i位置,模式串到j位置是否匹配。

class Solution {
public:bool isMatch(string s, string p) {int sLen = s.length();int pLen = p.length();if(sLen == 0){int pp = 0;while(pp<p.length() &&p[pp]=='*' ){pp++;}if(pp == p.length()) return true;else return false;}if(pLen == 0) return false;int len = 0;for(int i = 0;i < pLen;i++)  if(p[i] != '*') len++;  if(len > sLen) return false; bool dp[sLen][pLen];int i = 0, j = 0;for(;i<sLen;i++){for(;j<pLen;j++){dp[i][j]=false;}}if(p[0]=='*'){ //c;*?*for(i = 0;i < sLen; i++ ){dp[i][0] = true;}}//first line can appear one letter which is not starif (p[0]=='?' || s[0] == p[0]){ //first not-star-letter appearsdp[0][0] = true;for(j = 1;(j < pLen && p[j]=='*'); j++ ){dp[0][j]=true;}} else if(p[0]=='*'){ for(j = 1;(j < pLen && p[j-1]=='*'); j++ ){if(p[j]=='?' || s[0] == p[j]){ //first not-star-letter appearsdp[0][j]=true;j++;for(;j<pLen && p[j]=='*'; j++){ //after first not star, there should be all stardp[0][j]=true;}break;}else if(p[j]=='*'){dp[0][j]=true;}}}for(i = 1; i < sLen; i++){for(j = 1; j < pLen; j++){if(p[j]=='*'){dp[i][j] = dp[i-1][j] //* repeat 1 time|| dp[i][j-1]; //*repeat 0 times
                }else if(s[i]==p[j] || p[j]=='?'){dp[i][j] = dp[i-1][j-1];}}}return dp[sLen-1][pLen-1];}
};

时间复杂度:O(n2)

思路IV: 思路III的初始状态求法太复杂=>Solution:定义一个fake head。dp[0][0]表示两个空字符串的匹配情况,dp[0][0]=true.

class Solution {
public:bool isMatch(string s, string p) {int sLen = s.length();int pLen = p.length();if(sLen == 0){int pp = 0;while(pp<p.length() &&p[pp]=='*' ){pp++;}if(pp == p.length()) return true;else return false;}if(pLen == 0) return false;vector<vector<bool>> dp(sLen+1, vector<bool>(pLen+1,0));//initial statesint i = 0, j = 0;dp[0][0]=true;for(j = 1;(j <= pLen && p[j-1]=='*'); j++ ){dp[0][j]=true;}//state transferfor(i = 1; i <= sLen; i++){for(j = 1; j <= pLen; j++){if(p[j-1]=='*'){dp[i][j] = dp[i-1][j] //* repeat 1 time|| dp[i][j-1]; //*repeat 0 times
                }else if(s[i-1]==p[j-1] || p[j-1]=='?'){dp[i][j] = dp[i-1][j-1];}}}return dp[sLen][pLen];}
};

思路V:节约空间,状态之和i-1有关,所以只要记录上一行状态就可以。可以用一维数组。

class Solution {
public:bool isMatch(string s, string p) {int sLen = s.length();int pLen = p.length();if(sLen == 0){int pp = 0;while(pp<p.length() &&p[pp]=='*' ){pp++;}if(pp == p.length()) return true;else return false;}if(pLen == 0) return false;vector<bool> lastDP(pLen+1, 0);vector<bool> currentDP(pLen+1, 0);vector<bool> tmp;//initial statesint i = 0, j = 0;lastDP[0]=true;for(j = 1;(j <= pLen && p[j-1]=='*'); j++ ){lastDP[j]=true;}//state transferfor(i = 1; i <= sLen; i++){currentDP[0]=false;for(j = 1; j <= pLen; j++){if(p[j-1]=='*'){currentDP[j] = lastDP[j] //* repeat 1 time|| currentDP[j-1]; //*repeat 0 times
                }else if(s[i-1]==p[j-1] || p[j-1]=='?'){currentDP[j] = lastDP[j-1];}else{currentDP[j] = false;}}tmp = currentDP;currentDP = lastDP;lastDP = tmp;}return lastDP[pLen];}
};

转载于:https://www.cnblogs.com/qionglouyuyu/p/4856121.html

44. Wildcard Matching (String; DP, Back-Track)相关推荐

  1. LeetCode 10. Regular Expression Matching / 44. Wildcard Matching

    10. Regular Expression Matching 经典DP题目,比较复杂,需要多复习. dp[i][j] 表示 s 下标0~i,p 下标0~j 是否能够匹配   dp[i-1][j-1] ...

  2. LeetCode: 44. Wildcard Matching

    LeetCode: 44. Wildcard Matching 题目描述 Implement wildcard pattern matching with support for '?' and '* ...

  3. LeetCode - 44. Wildcard Matching

    44. Wildcard Matching Problem's Link --------------------------------------------------------------- ...

  4. 【To Understand! 重点 递归 动态规划 正则表达式匹配】LeetCode 44. Wildcard Matching

    LeetCode 44. Wildcard Matching Solution1:我的答案 递归,时间复杂度是O(2n)O(2n)O(2^n)因为超时未能AC 只是记录一下,以警示后人-- class ...

  5. 【LeetCode】44. Wildcard Matching (2 solutions)

    Wildcard Matching Implement wildcard pattern matching with support for '?' and '*'. '?' Matches any ...

  6. [LeetCode] #44 Wildcard Matching

    mplement wildcard pattern matching with support for '?' and '*'. '?' Matches any single character. ' ...

  7. [leetcode 44] Wildcard Matching

    Implement wildcard pattern matching with support for '?' and '*'. '? ' Matches any single character. ...

  8. 44. Wildcard Matching 通配符匹配

    Title 给定一个字符串 (s) 和一个字符模式 § ,实现一个支持 '?' 和 '*' 的通配符匹配. '?' 可以匹配任何单个字符. '*' 可以匹配任意字符串(包括空字符串). 两个字符串完全 ...

  9. [OJ] Wildcard Matching (Hard)

    LintCode 192. Wildcard Matching (Hard) LeetCode 44. Wildcard Matching (Hard) 第二次刷还是被这题虐. 其实就是跪在一个地方, ...

  10. [LeetCode] Wildcard Matching 题解

    6. Wildcard Matching 题目 Implement wildcard pattern matching with support for '?' and '*'. '?' Matche ...

最新文章

  1. linux安装深度软件商店,Deepin系统中的深度商店V5.1发布,基于Debian的Linux可安装...
  2. linux怎么卸载yam,linux 基本命令 - osc_foipyam7的个人空间 - OSCHINA - 中文开源技术交流社区...
  3. angular routerlink传递参数_[翻译]在 Angular 中使用 async-await 特性
  4. mysql 从服务器_如何使用mysql 主从服务器
  5. vue-cli搭建和“Cannot find module npm-cli.js” 、“operation not permitted” 、 deprecated coffee-script等错误
  6. ipv4广播地址怎么填_什么是IP地址?IP地址有什么用?网络工程师来告诉你
  7. 如何获取百度文库中的文章【原创】
  8. 双水泵轮换工作原理图_周宁气压给水设备控制柜原理图
  9. 数据:以太坊2.0合约质押新增4.15万ETH
  10. Springboot启动完毕后提供了立刻执行自定义程序的两个接口类
  11. 《学习OpenCV3》第4章 图像和大型数组类型(持续更新)
  12. 小猫钓鱼——栈和队列的应用(C++)
  13. 关于日记app的思考
  14. matlab 蠓虫,蠓虫分类.doc.doc
  15. 2020-11-29 漫谈email之smtp、pop3、spf dkim
  16. 基于Raspberry Pi(树莓派)的MCC数据采集卡应用
  17. Tomcat7 配置 WebSocket
  18. 丰田发布“大眼萌”机器人,只有手掌大小!
  19. 专利查新报告该怎么做?
  20. 【RISC-V】嵌入式开发小技巧之代码字体缩放!

热门文章

  1. C中得到4号错误(中断),怎么办
  2. 解决两个WINDOWS10的卡死问题
  3. 由蔺相如谈谈某些人的娱乐表演
  4. C# 提示框 鼠标移动到控件提示 toolTip气泡提示框
  5. linux ssl 脚本 51cto,升级opensslopenssh的shell脚本
  6. linux安装gcc-4.9,centos7.2编译安装gcc-4.9.2
  7. python脚本文件拓展名_python文件后缀
  8. 2014年4月管理计算机应用,全国2014年4月自考管理系统中计算机应用真题
  9. netbeans使用git_如何在我的NetBeans IDE中设置github存储库?
  10. css3媒体查询实例,css3 响应式媒体查询的示例代码