【WildCard Matching】cpp
题目:
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的更多相关文章
- 【 Regular Expression Matching 】cpp
题目: Implement regular expression matching with support for '.' and '*'. '.' Matches any single chara ...
- hdu 4739【位运算】.cpp
题意: 给出n个地雷所在位置,正好能够组成正方形的地雷就可以拿走..为了简化题目,只考虑平行于横轴的正方形.. 问最多可以拿走多少个正方形.. 思路: 先找出可以组成正方形的地雷组合cnt个.. 然后 ...
- 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~ ...
- 【Valid Sudoku】cpp
题目: Determine if a Sudoku is valid, according to: Sudoku Puzzles - The Rules. The Sudoku board could ...
- 【Permutations II】cpp
题目: Given a collection of numbers that might contain duplicates, return all possible unique permutat ...
- 【Subsets II】cpp
题目: Given a collection of integers that might contain duplicates, nums, return all possible subsets. ...
- 【Sort Colors】cpp
题目: Given an array with n objects colored red, white or blue, sort them so that objects of the same ...
- 【Sort List】cpp
题目: Sort a linked list in O(n log n) time using constant space complexity. 代码: /** * Definition for ...
- 【Path Sum】cpp
题目: Given a binary tree and a sum, determine if the tree has a root-to-leaf path such that adding up ...
随机推荐
- select 语句占位符
对于已预备的语句,可以使用位置保持符.以下语句将从tb1表中返回一行: mysql> SET @a=1; mysql> PREPARE STMT FROM "SELECT * F ...
- Android中SearchView修改字体颜色
首先获取searchView控件,比如在actionbar上获取: SearchView searchView = (SearchView) menu.findItem(R.id.action_sea ...
- 显示或隐藏一个Grid
The Rowset class contains two methods that can be used to show and hide all rows: ShowAllRows() Hide ...
- Knockout.Js官网学习(数组observable)
前言 如果你要探测和响应一个对象的变化,你应该用observables. 如果你需要探测和响应一个集合对象的变化,你应该用observableArray . 在很多场景下,它都非常有用,比如你要在UI ...
- php中的日期
1.在PHP中获取日期和时间 time()返回当前时间的 Unix 时间戳. getDate()返回日期/时间信息. gettimeofday()返回当前时间信息.date_sunrise()返回给定 ...
- C# 截取带路径的文件名字,扩展名,等等 的几种方法
C#对磁盘IO操作的时候,经常会用到这些,路径,文件,文件名字,文件扩展名. 之前,经常用切割字符串来实现, 可是经常会弄错. 尤其是启始位置,多少个字节,经常弄晕. 下面这种方法貌似比较简便: st ...
- C#之委托初步
传说中的东西,今天兴趣来了,就研究了研究,把大概什么是委托,如何使用委托稍微梳理了一下. 1.什么是委托 首先,Class(类)是对事物的抽象,例如,哺乳动物都是胎生,那么你可以定义一个哺乳动物的基类 ...
- 利用MVC编程模式-开发一个简易记事本app
学了极客学院一个开发记事本的课程,利用自己对MVC编程模式的简单理解重写了一遍该app. github地址:https://github.com/morningsky/MyNote MVC即,模型(m ...
- java基本概念
什么是环境变量? 环境变量通常是指在操作系统当中,用来指定操作系统运行时需要的一些参数.通常为一系列的键值对. path环境变量的作用 path环境变量是操作系统外部命令搜索路径 什么是外部命令搜索路 ...
- o2o家庭助手demo
前段时间跟一个同事出去游玩,在回来的大巴上面我们聊到了现在比较热门的o2o,说实话我自己早就想要在这个领域好好地玩一把.但是一直苦于没有很好地idea,再加上自己之前一直没有这方面的创业经验,所以一直 ...