目录
leetcode-10 Regular Expression Matching 正则表达式匹配
leetcode-44 Wildcard Matching 通配符匹配
leetcode-10 Regular Expression Matching 正则表达式匹配
Given an input string ( The matching should cover the entire input string (not partial). Note:
|
class Solution:
def isMatch(self, s: str, p: str) -> bool:
# 边界条件,考虑 s 或 p 分别为空的情况
if not p: return not s
if not s and len(p) == 1: return False
m, n = len(s) + 1, len(p) + 1
dp = [[False for _ in range(n)] for _ in range(m)]
# 初始状态
dp[0][0] = True
dp[0][1] = False
for c in range(2, n):
j = c - 1
if p[j] == '*':
dp[0][c] = dp[0][c - 2]
for r in range(1,m):
i = r - 1
for c in range(1, n):
j = c - 1
if s[i] == p[j] or p[j] == '.':
dp[r][c] = dp[r - 1][c - 1]
elif p[j] == '*': # ‘*’前面的字符匹配s[i] 或者为'.'
if p[j - 1] == s[i] or p[j - 1] == '.':
dp[r][c] = dp[r - 1][c] or dp[r][c - 2]
else: # ‘*’匹配了0次前面的字符
dp[r][c] = dp[r][c - 2]
else:
dp[r][c] = False
return dp[m - 1][n - 1]
class Solution {
public:
bool isMatch(string s, string p) {
return regex_match(s, regex(p));
}
};
leetcode-44 Wildcard Matching 通配符匹配
Given an input string ( The matching should cover the entire input string (not partial). Note:
|
方法1.
class Solution {
public boolean isMatch(String s, String p) {
int sLen = s.length(), pLen = p.length();
if (p.equals(s) || p.equals("*")) return true;
if (p.isEmpty() || s.isEmpty()) return false;
// init all matrix except [0][0] element as False
boolean[][] d = new boolean[pLen + 1][sLen + 1];
d[0][0] = true;
// DP compute
for(int pIdx = 1; pIdx < pLen + 1; pIdx++) {
if (p.charAt(pIdx - 1) == '*') {
int sIdx = 1;
while ((!d[pIdx - 1][sIdx - 1]) && (sIdx < sLen + 1)) sIdx++;
d[pIdx][sIdx - 1] = d[pIdx - 1][sIdx - 1];
while (sIdx < sLen + 1) d[pIdx][sIdx++] = true;
}
else if (p.charAt(pIdx - 1) == '?') {
for(int sIdx = 1; sIdx < sLen + 1; sIdx++)
d[pIdx][sIdx] = d[pIdx - 1][sIdx - 1];
}
else {
for(int sIdx = 1; sIdx < sLen + 1; sIdx++) {
d[pIdx][sIdx] = d[pIdx - 1][sIdx - 1] &&
(p.charAt(pIdx - 1) == s.charAt(sIdx - 1));
}
}
}
return d[pLen][sLen];
}
}
方法2.
算法:
我们使用两个指针:i
遍历输入字符串,j
遍历字符模式串。当 i < s_len
:
- 如果字符模式仍有字符
j < p_len
且指针下的字符匹配p[j] == s[i]
或p[j] == '?'
,则两个指针向前移动。 - 反之如果字符模式仍有字符
j < p_len
且p[j] == '*'
,则首先检查匹配 0 字符的情况,即只增加模式指针j++
。记下可能回溯的位置jstar
和当前字符串的位置 istar。 - 反之如果出现不匹配的情况:
- 如果字符模式中没有星号,则返回
False
。 - 如果有星号,则回溯:设置
j = jstar + 1
和i =
istar+ 1
,假设这次的星匹配多个字符。则可能的回溯为 istar= i
。
- 如果字符模式中没有星号,则返回
- 如果字符模式的所有剩余字符都是星号,则返回
True
。
例:s="abcdefghe" p="a*e"
class Solution {
public:
bool isMatch(string s, string p) {
int i = 0, j = 0, iStar = -1, jStar = -1, m = s.size(), n = p.size();
while (i < m) {
if (j < n && (s[i] == p[j] || p[j] == '?')) {
++i, ++j;
} else if (j < n && p[j] == '*') {
iStar = i;
jStar = j++;
} else if (iStar >= 0) {
i = ++iStar;
j = jStar + 1;
} else return false;
}
while (j < n && p[j] == '*') ++j;//去除多余星号
return j == n;
}
};