题目:
给你一个字符串 s 和一个字符规律 p,请你来实现一个支持 ‘.’ 和 ‘*’ 的正则表达式匹配。
‘.’ 匹配任意单个字符
‘*’ 匹配零个或多个前面的那一个元素
所谓匹配,是要涵盖 整个 字符串 s的,而不是部分字符串。
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/regular-expression-matching
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
思路:
动态规划
既然是要用到动态规划,那小编就写一下我认为的动态规划的几个步骤:
- 设置状态函数f();并明白其作用,一般为前i个的结果是什么。
本题是f(i,j)
返回字符串s的前i个字符,字符串p前j个字符的匹配结果
- 用状态函数表示要求的结果
字符串s的长度为m,字符串n的长度为n,
f(m,n)
为要求的结果
- 写出状态转移方程,相当于一个递推公式
- 标注临界值,直接枚举临界的情况
if (i == 0 && j == 0) return true;
else if (j == 0) return false;
else if (i == 0){
if (j%2 == 0)return p.charAt(j - 1) == '*' && getMN(i, j - 2);
else return false;
}
- 代码书写,必然会用到递归
- 设置缓存,实现代码运行优化
动态规划会涉及很多重复的子问题,如果我们把一些结果缓存起来,在调用之前先看缓存里面有没有,没有再运行,这在遇到重复的地方直接调用缓存就会提高运行速度。
ArrayList<songsong> arr = new ArrayList<>();
//缓存的数据结构
class songsong{
int i;
int j;
boolean okk;
songsong(int i,int j,boolean okk){
this.i = i;
this.j = j;
this.okk = okk;
}
}
//把结果先缓存,再返回。
oneArr.okk = result;
arr.add(oneArr);
return result;
//搜索缓存
for (int k = 0;k<arr.size();k++){
if (arr.get(k).i == i && arr.get(k).j == j){
return arr.get(k).okk;
}
}
代码:
import java.util.ArrayList;
class Solution {
String s ;
String p ;
ArrayList<songsong> arr = new ArrayList<>();
public boolean isMatch(String s, String p) {
this.s = s;
this.p = p;
int m = s.length(),n=p.length();
boolean result = getMN(m, n);
System.out.println();
return result;
}
private boolean getMN(int i, int j) {
//临界值
if (i == 0 && j == 0) return true;
else if (j == 0) return false;
else if (i == 0){
if (j%2 == 0)return p.charAt(j - 1) == '*' && getMN(i, j - 2);
else return false;
}
//搜索缓存
for (int k = 0;k<arr.size();k++){
if (arr.get(k).i == i && arr.get(k).j == j){
return arr.get(k).okk;
}
}
songsong oneArr = new songsong(i,j,false);
boolean result = true;
//状态转移方程
if (p.charAt(j-1) != '*') {
if (isok(i, j)) {
result = getMN(i-1,j-1);
}else {
result = false;
}
}else {
if (!isok(i,j-1)){
result= getMN(i,j-2);
}else {
result= getMN(i,j-2) || getMN(i-1,j);
}
}
oneArr.okk = result;
arr.add(oneArr);
return result;
}
private boolean isok(int i, int j) {
if (p.charAt(j-1)=='.' || s.charAt(i-1) == p.charAt(j-1)) return true;
else return false;
}
class songsong{
int i;
int j;
boolean okk;
songsong(int i,int j,boolean okk){
this.i = i;
this.j = j;
this.okk = okk;
}
}
}