[LeetCode]10. Regular Expression Matching正则表达式匹配
Given an input string (s) and a pattern (p), 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).
Note:
s could be empty and contains only lowercase letters a-z.
p could be empty and contains only lowercase letters a-z, and characters like . or *.
Example 1:
Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".
Example 2:
Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".
Example 3:
Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".
Example 4:
Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".
Example 5:
Input:
s = "mississippi"
p = "mis*is*p*."
Output: false
题目要求判断给出的表达式p能否匹配字符串s,其中"."能匹配任意字符,"*"能匹配前一个字符任意多次,比如"a*",可以匹配空字符,或者任意多个a,基于本题中
"*"可以是0个,所以不能由前面不匹配就得出后面也不匹配的结论,比如s=b,p=a*b,一开始a!=b,我们不能由这个结论得出整个字符串不匹配,所以这题我们需要把整个字符串匹配完。
这题我的做法是DP,假设dp[i][j]表示匹配到S[:i]与P[:j]
(1)p[j]=!'*',此时p[j]可能是字符,那就需要S[i]==P[j],可能是".",肯定匹配
dp[i][j] = dp[i-1][j-1] && ( s[i]==p[j] || p[j]=='.' )
(2)P[j]=='*',此时需要根据*的重复次数分情况讨论
- 重复0次,此时p[j]的作用就是消去前一个字符的作用,所以dp[i][j] = dp[i][j-2]
- 重复1次或以上,需要看p[j-1]的这个字符能否匹配S[i]这个位置的字符,
也就是S[i]==P[j-1]&&P[j-1]=='.',再来看dp[i][j]是从哪一个状态转化来的,假设
S=abbbb,p=ab*,要求dp[1][1]时,此时dp[0][]已经全部得出来了,dp[1][1]=dp[0][1],
dp[0][1]到dp[1][1]是"*"从重复0次到1次的变化,然后是dp[2][2]=dp[1][2],我们可以总结出,
dp[i][j]的状态是"*"重复次数增加带来的状态变化,变化前是dp[i-1][j],也就是"*"重复次数增加前的状态。所以dp[i][j] = dp[i-1][j] && ( S[i]==P[j-1] || P[j-1]=='.' )
综上所述
dp[i][j] = dp[i-1][j-1] && ( s[i]==p[j] || p[j]=='.' ) ,条件是p[j]=!'*'
dp[i][j] = dp[i][j-2],条件是P[j]=='*',并且重复0次
dp[i][j] = dp[i-1][j] && ( S[i]==P[j-1] || P[j-1]=='.' ),条件是P[j]=='*'并重复不止1次
因为存在i-1,j-2这样的状态,为了防止数组越界,我们把S和P都向后移动一个位置,就当添加了一个空格" "进去,这样S和P的比较都是从1开始了,所有的判断条件需要多减一位
同时,简化"*"重复次数的不同状态,因为"*"重复0次不需要任何条件,dp[i][j] = dp[i][j - 2] || i > 0 && dp[i - 1][j] && (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.')
class Solution {
public boolean isMatch(String s, String p) {
int m = s.length(), n = p.length();
boolean dp[][] = new boolean[m + 1][n + 1];
dp[0][0] = true;
for(int i = 0; i <= m; ++i) {
for(int j = 1; j <= n; ++j) {
if(p.charAt(j - 1) == '*') {
dp[i][j] = dp[i][j - 2] || i > 0 && dp[i - 1][j] && (s.charAt(i - 1) == p.charAt(j - 2) || p.charAt(j - 2) == '.');
} else {
dp[i][j] = i > 0 && dp[i - 1][j - 1] && (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '.');
}
}
}
return dp[m][n];
}
}
还有其他方法,像递归求解
若p为空,若s也为空,返回true,反之返回false
若p的长度为1,若s长度也为1,且相同或是p为'.'则返回true,反之返回false
若p的第二个字符不为*,若此时s为空返回false,否则判断首字符是否匹配,且从各自的第二个字符开始调用递归函数匹配
若p的第二个字符为*,若s不为空且字符匹配,调用递归函数匹配s和去掉前两个字符的p,若匹配返回true,否则s去掉首字母
返回调用递归函数匹配s和去掉前两个字符的p的结果
class Solution {
public boolean isMatch(String s, String p) {
if (p.isEmpty()) return s.isEmpty();
if (p.length() == 1) {
return (s.length() == 1 && (s.charAt(0) == p.charAt(0)|| p.charAt(0) == '.'));
}
if (p.charAt(1)!= '*') {
if (s.isEmpty()) return false;
return (s.charAt(0) == p.charAt(0) || p.charAt(0) == '.') && isMatch(s.substring(1), p.substring(1));
}
while (!s.isEmpty() && (s.charAt(0) ==p.charAt(0) || p.charAt(0) == '.')) {
if (isMatch(s, p.substring(2))) return true;
s = s.substring(1);
}
return isMatch(s, p.substring(2));
}
}
[LeetCode]10. Regular Expression Matching正则表达式匹配的更多相关文章
- [LeetCode] 10. Regular Expression Matching 正则表达式匹配
Given an input string (s) and a pattern (p), implement regular expression matching with support for ...
- [leetcode]10. Regular Expression Matching正则表达式的匹配
Given an input string (s) and a pattern (p), implement regular expression matching with support for ...
- 10. Regular Expression Matching正则表达式匹配
Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...
- leetcode 10 Regular Expression Matching(简单正则表达式匹配)
最近代码写的少了,而leetcode一直想做一个python,c/c++解题报告的专题,c/c++一直是我非常喜欢的,c语言编程练习的重要性体现在linux内核编程以及一些大公司算法上机的要求,pyt ...
- Leetcode 10. Regular Expression Matching(递归,dp)
10. Regular Expression Matching Hard Given an input string (s) and a pattern (p), implement regular ...
- leetcode 10. Regular Expression Matching 、44. Wildcard Matching
10. Regular Expression Matching https://www.cnblogs.com/grandyang/p/4461713.html class Solution { pu ...
- [LeetCode] Regular Expression Matching 正则表达式匹配
Implement regular expression matching with support for '.' and '*'. '.' Matches any single character ...
- LeetCode (10): Regular Expression Matching [HARD]
https://leetcode.com/problems/regular-expression-matching/ [描述] Implement regular expression matchin ...
- 蜗牛慢慢爬 LeetCode 10. Regular Expression Matching [Difficulty: Hard]
题目 Implement regular expression matching with support for '.' and '*'. '.' Matches any single charac ...
随机推荐
- Dialog 自定义使用2(进度条)
1: 自定义的Dialog 代码: public class IphoneProgersssDialog extends Dialog { private Context context; priv ...
- 2、linux-compress and uncompresse
1.单个文件 压缩 解压 gzip file1 gzip -d file1.gz或者gunzip file1.gz #file1文件即会被压缩为 file1.gz,file1原文件删除:解压后同样删 ...
- 如何设置 Windows 默认命令行窗口大小和缓冲区大小
关键字: 命令行不能全屏 命令行最大化只有一半屏幕 命令行 字体 背景 颜色 解决方案:http://unmi.cc/save-windows-command-size/ 简要说明: win+r,输入 ...
- Python短小精悍的Orator基本使用技巧
基本使用 配置 设置数据库配置参数,创建一个DatabaseManager实例. from orator import DatabaseManager config = { 'mysql': { 'd ...
- Mysql分片后分页排序拉取数据的方法
高并发大流量的互联网架构,一般通过服务层来访问数据库,随着数据量的增大,数据库需要进行水平切分,分库后将数据分布到不同的数据库实例(甚至物理机器)上,以达到降低数据量,增加实例数的扩容目的. 一旦涉及 ...
- Boost Python学习笔记(三)
你将学到什么 在C++中调用Python代码时的传参问题 基础类型 继续使用前面的项目,但是先修改下Python脚本(zoo.py),添加Add和Str函数,分别针对整数.浮点数和字符串参数的测试 d ...
- java解析xml实例——获取天气信息
获取xml并解析其中的数据: package getweather.xml; import java.io.IOException; import java.util.HashMap; import ...
- 【转】vs发布msi程序详解
源地址:http://wenku.baidu.com/link?url=MV1Mf7IukCZ0cab8AzXQoQ3MAXeUAHGz5b2IuUL4Kw-hCI90ZyBKXwKeQA3t3-SV ...
- Cogs 1264. [NOIP2012] 开车旅行(70分 暴力)
1264. [NOIP2012] 开车旅行 ★★☆ 输入文件:drive.in 输出文件:drive.out 简单对比时间限制:2 s 内存限制:128 MB [题目描述] 小A 和小 ...
- 剑指Offer的学习笔记(C#篇)-- 旋转数组的最小数字
题目描述 把一个数组最开始的若干个元素搬到数组的末尾,我们称之为数组的旋转. 输入一个非减排序的数组的一个旋转,输出旋转数组的最小元素. 例如数组{3,4,5,1,2}为{1,2,3,4,5}的一个旋 ...