题意:

Implement regular expression matching with support for '.' and '*'.

'.' 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", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true (hard) 分析:
题目意思是 正则表达式匹配,'.'匹配任意字符, '*'表示前一个字符可以出现任意多次(0次,1次,2次...)
如ab 与 .* :将.出现两次为..可以匹配任意字符,所有可以匹配ab
aab 与 c*a*b :c*将c出现0次, a*将a出现两次,得到aab可以匹配。 而且特殊符号是只出现在p字符串中的(开始没理解这个导致感觉问题很复杂推不下去...,可能因为没学过正则表达式) 解析:
采用动态规划。双序列动态规划常见得状态选取即为dp[i][j]表示s的前i个与p的前j个...
对应于本题,dp[i][j]表示s的前i个字符与p的前j个字符能否匹配。 但本题递推关系不是很好推完整(毕竟hard)
当p[j-1] != '*'
    需要s[i-1] == p[j-1] 并且 dp[i-1][j-1] == true (前i-1个与前j-1个能匹配)
当p[j-1] == '*'
    有如下几种情况:
    1)*前的字符需要重复0次 例如匹配 ab 和 aba*, 该情况下dp[i][j]是否为真取决于 dp[i][j-2] 是否为真;
    2)*前的字符需要重复1次,即其本身,如匹配 aba 和 aba*, 该情况下dp[i][j]是否为真取决于dp[i][j-1]是否为真;
    3)*前字符需要重复2次或以上, 如匹配 abaa 与 aba*(出现两次), 匹配aaa与.*(出现大于两次);
      该情况下需要s[i-1] == p[j-2] && (dp[i-1][j-1] || dp[i-1][j]) // dp[i-1][j]容易忽略,表示要利用*前元素大于两次; 初始化dp[0][0], dp[i][0] (i = 1,2,...s.size()) , dp[0][j], (j = 1,2,...p.size());
其中dp[0][j]的需要点判断, p[j - 1] == '*' &&  dp[0][j - 2] (即*帮助去掉了前面的字符。开始还写了||dp[0][j-1],后来发现*不会打头存在,所以dp[0][j-1]没必要) 代码:(还有一些小细节在注释中)
 class Solution {
public:
bool isMatch(string s, string p) {
bool dp[s.size() + ][p.size() + ];
dp[][] = true;
for (int i = ; i <= s.size(); ++i) {
dp[i][] = false;
}
for (int j = ; j <= p.size(); ++j) {
//p[j-2]一定存在,*不会打头!
if (p[j - ] == '*' && dp[][j - ]) {
dp[][j] = true;
}
else {
dp[][j] = false;
}
} for (int i = ; i <= s.size(); ++i) {
for (int j = ; j <= p.size(); ++j) {
if (p[j - ] != '*') {
dp[i][j] = (s[i - ] == p[j - ] || p[j - ] == '.') && dp[i - ][j - ];
}
else {
//重复两次或更多 dp[i-1][j] 如:aaa与.*
// * 不会打头,所以p[j - 2]一定存在
bool b1 = (s[i - ] == p[j - ] || p[j - ] == '.') && (dp[i - ][j - ] || dp[i - ][j]);
bool b2 = dp[i][j - ]; //重复1次
bool b3 = dp[i][j - ]; //重复0次
dp[i][j] = b1 || b2 || b3;
}
}
}
return dp[s.size()][p.size()];
}
};
学习了一下讨论区,发现递推的情况基本是一样的,有一点细微的优化。

我做的时候是先想到类似abaa 与 aba*, *前字符重复两次,所以写出了dp[i - 1][j - 1]。(标红前半句)
提交之后WA发现有情况没考虑到,即aaa与.* 即出现大于两次,所以添加了dp[i-1][j]
而现在仔细考虑,实际上只需要一句dp[i-1][j]就可以处理大于等于2次重复的情况,所以标红句可以优化为
bool b1 = (s[i - ] == p[j - ] || p[j - ] == '.') &&  dp[i - ][j];

 

												

LeetCode10 Regular Expression Matching的更多相关文章

  1. [Swift]LeetCode10. 正则表达式匹配 | Regular Expression Matching

    Given an input string (s) and a pattern (p), implement regular expression matching with support for  ...

  2. [LeetCode] Regular Expression Matching 正则表达式匹配

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  3. [LeetCode] 10. Regular Expression Matching

    Implement regular expression matching with support for '.' and '*'. DP: public class Solution { publ ...

  4. No.010:Regular Expression Matching

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

  5. Regular Expression Matching

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  6. 【leetcode】Regular Expression Matching

    Regular Expression Matching Implement regular expression matching with support for '.' and '*'. '.' ...

  7. 【leetcode】Regular Expression Matching (hard) ★

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

  8. 66. Regular Expression Matching

    Regular Expression Matching Implement regular expression matching with support for '.' and '*'. '.' ...

  9. 【JAVA、C++】LeetCode 010 Regular Expression Matching

    Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...

随机推荐

  1. 怎么从sqlserver 数据库导出 insert 的数据语句

    In SSMS in the Object Explorer, right click on the database right-click and pick "Tasks" a ...

  2. 第三百五十二天 how can I 坚持

    如果要是今年找不到对象,明年去回济南, 怎么感觉那么不舍呢.生活总是有太多的无奈啊. 今天加了一天,倒是没感觉,只是感觉生活太空虚. 或许遗憾只是因为自己太懦弱.怎么说呢,还是那句话,经历的就会成长, ...

  3. 第三百三十三天 how can I 坚持

    为什么感觉那么累呢,老想睡觉. 晚上勇江请吃饭,其实内心是拒绝的,好伐,老想回家尽快睡觉. 今天说是要搞oauth认证的东西,看的一头雾水. 想的太简单了.其实也不难.apache的东西,都封装好的. ...

  4. JXSE and Equinox Tutorial, Part 2

    http://java.dzone.com/articles/jxse-and-equinox-tutorial-part-0 ———————————————————————————————————— ...

  5. HTML5边玩边学(1)画布实现方法

    一.<canvas>标签 Html5 引入了一个新的 <canvas> 标签,这个标签所代表的区域就好象一块画布,你的所有图形绘制最后都要在这块画布上呈现.有了这个标签,浏览器 ...

  6. HTML结构标签介绍

    HTML:超文本标记语言   介绍HTML基本标记   1:头部标记(head)-----  头部的内容不会再页面上显示 在头部元素中,一般需要包括标题<title>,基本信息(文档样式, ...

  7. sqlserver 自增字段修改为普通主键字段

    --增加备份字段alter Table tableName add columnNameBak bigint ; --将主键自增字段 赋值到备份字段update tableNameset column ...

  8. Json.Net学习笔记

    http://www.cnblogs.com/xiaojinhe2/archive/2011/10/28/2227789.html Newtonsoft.Json(Json.Net)学习笔记 http ...

  9. C#以及Oracle中的上取整、下取整方法

    1.C#中: 上取整——Math.Ceiling(Double),即返回大于或等于指定双精度浮点数的最大整数(也可称为取天板值): eg:  Math.Ceiling(1.01)=2;      Ma ...

  10. CriminalIntent程序中Fragment相关内容

    Activity中托管UI fragment有两种方式: 添加fragment到acitivity中 在activity代码中添加fragment 第一种方法即将fragment添加到acitivit ...