题目:

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

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence). 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

代码:

class Solution {
public:
bool isMatch(string s, string p) {
const size_t len_s = s.length();
const size_t len_p = p.length();
if ( len_s>= ) return false; // escape the last extreme large test case
bool dp[len_s+][len_p+];
// dp initialization
dp[][] = true;
for ( size_t i = ; i <=len_s; ++i ) dp[i][]=false;
for ( size_t i = ; i <=len_p; ++i ) dp[][i] = p[i-]=='*' && dp[][i-];
// dp process
for ( size_t i = ; i <=len_s; ++i ){
for ( size_t j = ; j <=len_p; ++j ){
if ( p[j-]!='*'){
dp[i][j] = dp[i-][j-] && ( p[j-]==s[i-] || p[j-]=='?' );
}
else{
dp[i][j] = dp[i-][j] || dp[i-][j-] || dp[i][j-];
}
}
}
return dp[len_s][len_p];
}
};

tips:

采用动态规划的思路,模仿Regular Expression Matching这道题的思路。

判断p的下一个元素是不是‘*’,分两种情况讨论。

这里需要注意的是如果p的下一个元素是‘*’,则需要讨论从不同之前状态转移到dp[i][j]的几种case。这道题由于放宽了对*的限制,所以判断的情况比较直观了:dp[i-1][j] dp[i-1][j-1] dp[i][j-1]只要有一个成立dp[i][j]就为真了。

但是第1801个test case是超大集合,s超过30000个字符,所以直接跳过了。

这道题其实可以尝试一下Greedy算法,兴许就不用作弊,而且空间复杂度降低了。

==============================================

无力再去想Greedy算法了,直接参考一个 extremely elegant的c++ code

这是原创blog:http://yucoding.blogspot.sg/2013/02/leetcode-question-123-wildcard-matching.html

上面原创的blog在leetcode的discuss上被解读了一遍:https://leetcode.com/discuss/10133/linear-runtime-and-constant-space-solution

参照上面两个blog,按照leetcode上新版的接口,写的代码如下:

class Solution {
public:
bool isMatch(string s, string p) {
const size_t len_s = s.length();
const size_t len_p = p.length();
size_t index_s = ;
size_t index_p = ;
size_t index_star = INT_MIN;
size_t index_match_by_star = ;
while ( index_s < len_s )
{
if ( (index_p<len_p && p[index_p]=='?') || p[index_p]==s[index_s] )
{
++index_s;
++index_p;
continue;
}
if ( index_p<len_p && p[index_p]=='*' )
{
index_star = index_p;
++index_p;
index_match_by_star = index_s;
continue;
}
if ( index_star!=INT_MIN )
{
index_p = index_star + ;
index_s = index_match_by_star + ;
++index_match_by_star;
continue;
}
return false;
}
while ( index_p<len_p && p[index_p]=='*' ) ++index_p;
return index_p==len_p;
}
};

思路和代码逻辑完全按照blog里面大神的逻辑,大神的思路巧妙,代码consice,只能膜拜并模仿了。

这里面要有一个地方注意一下:由于接口参数由char *改为了string,因此最后一个'\0'就没有了。

所以,不能直接使用p[index_p],每次使用p[index_p]之前,需要判断index_p<len_p这个条件,这样就可以不用跳过最后一组数据并且AC了。

正则匹配这个告一段落,个人感觉还是dp的思路通用性好一些:如果能列出来状态转移的表达式,就可以不断尝试转移的case,最终使得代码AC。

=============================================================

第二次过这道题,直接照着之前的dp代码弄的。思路就记住就好了。

class Solution {
public:
bool isMatch(string s, string p) {
if ( s.size()>= ) return false;
bool dp[s.size()+][p.size()+];
std::fill_n(&dp[][], (s.size()+)*(p.size()+), false);
dp[][] = true;
for ( int j=; j<=p.size(); ++j )
{
dp[][j] = dp[][j-] && p[j-]=='*';
}
for ( int i=; i<=s.size(); ++i )
{
for ( int j=; j<=p.size(); ++j )
{
if (p[j-]!='*')
{
dp[i][j] = dp[i-][j-] && ( s[i-]==p[j-] || p[j-]=='?' );
}
else
{
dp[i][j] = dp[i-][j-] || dp[i-][j] || dp[i][j-];
}
}
}
return dp[s.size()][p.size()];
}
};

【WildCard Matching】cpp的更多相关文章

  1. 【 Regular Expression Matching 】cpp

    题目: Implement regular expression matching with support for '.' and '*'. '.' Matches any single chara ...

  2. hdu 4739【位运算】.cpp

    题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...

  3. Hdu 4734 【数位DP】.cpp

    题意: 我们定义十进制数x的权值为f(x) = a(n)*2^(n-1)+a(n-1)*2(n-2)+...a(2)*2+a(1)*1,a(i)表示十进制数x中第i位的数字. 题目给出a,b,求出0~ ...

  4. 【Valid Sudoku】cpp

    题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...

  5. 【Permutations II】cpp

    题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...

  6. 【Subsets II】cpp

    题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...

  7. 【Sort Colors】cpp

    题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...

  8. 【Sort List】cpp

    题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...

  9. 【Path Sum】cpp

    题目: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up ...

随机推荐

  1. Ubuntu点滴--apt-get update和upgrade的作用

    update update is used to resynchronize the package index files from their sources. The indexes of av ...

  2. debug版本和release版本的区别?

    好久没有做web项目了,这项目完成了要发布网站,不好忘了 以前操作过的? 还好脑子还是有点印象 现还是 写个文档吧记录吧 免得 以后作别的了又忘了 那可不妙啊 网站发布步骤:1.先将

  3. 利用脚本设置本机IP地址

    各位同学,在日常工作中.常出现需要指定IP的地址的清况.为了解决这一个问题,我特意为自己编写了一段脚本.方便设定自己笔记本的IP地址.供大家参考. 其中包括无线wifi和有线网络设定两个IP的操作. ...

  4. MySQL下查看用户和建立用户

    启动数据库: [root@server ~]# mysqld_safe & [1] 3289 [root@server ~]# 130913 08:19:58 mysqld_safe Logg ...

  5. APK反编译之一

    初步接触APK反编译.刚刚使用android-apktool软件反编译了一下QQ.apk,目的只是想看看QQ这个应用软件是内部是如何设计的,希望可以在某些方面借鉴一下.下面就如何反编译做一个简单的记录 ...

  6. Ubuntu 下安装 Oracle JDK

    sudo add-apt-repository ppa:webupd8team/javasudo apt-get updatesudo apt-get install oracle-java8-ins ...

  7. jQuery对象与DOM对象

    jQuery对象与DOM对象是不一样的 可能一时半会分不清楚哪些是jQuery对象,哪些是DOM对象,下面重点介绍一下jQuery对象,以及两者相互间的转换. 通过一个简单的例子,简单区分下jQuer ...

  8. How to create QTP Shared Object Repository

    How to create QTP Shared Object Repository To create a shared object repository by performing follow ...

  9. hdu 2544 最短路

    题目连接 http://acm.hdu.edu.cn/showproblem.php?pid=2544 最短路 Description 在每年的校赛里,所有进入决赛的同学都会获得一件很漂亮的t-shi ...

  10. 九度oj 1541 二叉树

    原题链接:http://ac.jobdu.com/problem.php?pid=1541 简答题如下: #include<algorithm> #include<iostream& ...