bool isMatch(string s, string p) {
function<bool(int, int)> match = [&](int i, int j) -> bool {
if (j == (int)p.size()) return i == (int)s.size();
bool first = i < (int)s.size() && (p[j] == '.' || p[j] == s[i]);
if (j + 1 < (int)p.size() && p[j + 1] == '*') {
return match(i, j + 2) || (first && match(i + 1, j));
}
return first && match(i + 1, j + 1);
};
return match(0, 0);
}
public boolean isMatch(String s, String p) {
return match(s, p, 0, 0);
}
private boolean match(String s, String p, int i, int j) {
if (j == p.length()) return i == s.length();
boolean first = i < s.length() && (p.charAt(j) == '.' || p.charAt(j) == s.charAt(i));
if (j + 1 < p.length() && p.charAt(j + 1) == '*') {
return match(s, p, i, j + 2) || (first && match(s, p, i + 1, j));
}
return first && match(s, p, i + 1, j + 1);
}
def is_match(s, p):
def match(i, j):
if j == len(p): return i == len(s)
first = i < len(s) and (p[j] == '.' or p[j] == s[i])
if j + 1 < len(p) and p[j + 1] == '*':
return match(i, j + 2) or (first and match(i + 1, j))
return first and match(i + 1, j + 1)
return match(0, 0)
function isMatch(s: string, p: string): boolean {
const match = (i: number, j: number): boolean => {
if (j === p.length) return i === s.length;
const first = i < s.length && (p[j] === '.' || p[j] === s[i]);
if (j + 1 < p.length && p[j + 1] === '*') {
return match(i, j + 2) || (first && match(i + 1, j));
}
return first && match(i + 1, j + 1);
};
return match(0, 0);
}
bool isMatch(string s, string p) {
unordered_map<int, bool> memo;
function<bool(int, int)> match = [&](int i, int j) -> bool {
if (j == (int)p.size()) return i == (int)s.size();
int key = i * ((int)p.size() + 1) + j;
auto it = memo.find(key);
if (it != memo.end()) return it->second;
bool first = i < (int)s.size() && (p[j] == '.' || p[j] == s[i]);
bool result;
if (j + 1 < (int)p.size() && p[j + 1] == '*') result = match(i, j + 2) || (first && match(i + 1, j));
else result = first && match(i + 1, j + 1);
memo[key] = result;
return result;
};
return match(0, 0);
}
public boolean isMatch(String s, String p) {
Map<Integer, Boolean> memo = new HashMap<>();
return match(s, p, 0, 0, memo);
}
private boolean match(String s, String p, int i, int j, Map<Integer, Boolean> memo) {
if (j == p.length()) return i == s.length();
int key = i * (p.length() + 1) + j;
if (memo.containsKey(key)) return memo.get(key);
boolean first = i < s.length() && (p.charAt(j) == '.' || p.charAt(j) == s.charAt(i));
boolean result;
if (j + 1 < p.length() && p.charAt(j + 1) == '*') result = match(s, p, i, j + 2, memo) || (first && match(s, p, i + 1, j, memo));
else result = first && match(s, p, i + 1, j + 1, memo);
memo.put(key, result);
return result;
}
def is_match(s, p):
memo = {}
def match(i, j):
if j == len(p): return i == len(s)
key = i * (len(p) + 1) + j
if key in memo: return memo[key]
first = i < len(s) and (p[j] == '.' or p[j] == s[i])
if j + 1 < len(p) and p[j + 1] == '*': result = match(i, j + 2) or (first and match(i + 1, j))
else: result = first and match(i + 1, j + 1)
memo[key] = result
return result
return match(0, 0)
function isMatch(s: string, p: string): boolean {
const memo = new Map<number, boolean>();
const match = (i: number, j: number): boolean => {
if (j === p.length) return i === s.length;
const key = i * (p.length + 1) + j;
if (memo.has(key)) return memo.get(key)!;
const first = i < s.length && (p[j] === '.' || p[j] === s[i]);
let result: boolean;
if (j + 1 < p.length && p[j + 1] === '*') result = match(i, j + 2) || (first && match(i + 1, j));
else result = first && match(i + 1, j + 1);
memo.set(key, result);
return result;
};
return match(0, 0);
}
bool isMatch(string s, string p) {
int m = s.size(), n = p.size();
vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false));
dp[m][n] = true;
for (int i = m; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
bool first = i < m && (p[j] == '.' || p[j] == s[i]);
if (j + 1 < n && p[j + 1] == '*') dp[i][j] = dp[i][j + 2] || (first && dp[i + 1][j]);
else dp[i][j] = first && dp[i + 1][j + 1];
}
}
return dp[0][0];
}
public boolean isMatch(String s, String p) {
int m = s.length(), n = p.length();
boolean[][] dp = new boolean[m + 1][n + 1];
dp[m][n] = true;
for (int i = m; i >= 0; i--) {
for (int j = n - 1; j >= 0; j--) {
boolean first = i < m && (p.charAt(j) == '.' || p.charAt(j) == s.charAt(i));
if (j + 1 < n && p.charAt(j + 1) == '*') dp[i][j] = dp[i][j + 2] || (first && dp[i + 1][j]);
else dp[i][j] = first && dp[i + 1][j + 1];
}
}
return dp[0][0];
}
def is_match(s, p):
m, n = len(s), len(p)
dp = [[False] * (n + 1) for _ in range(m + 1)]
dp[m][n] = True
for i in range(m, -1, -1):
for j in range(n - 1, -1, -1):
first = i < m and (p[j] == '.' or p[j] == s[i])
if j + 1 < n and p[j + 1] == '*': dp[i][j] = dp[i][j + 2] or (first and dp[i + 1][j])
else: dp[i][j] = first and dp[i + 1][j + 1]
return dp[0][0]
function isMatch(s: string, p: string): boolean {
const m = s.length, n = p.length;
const dp = Array.from({ length: m + 1 }, () => new Array<boolean>(n + 1).fill(false));
dp[m][n] = true;
for (let i = m; i >= 0; i--) {
for (let j = n - 1; j >= 0; j--) {
const first = i < m && (p[j] === '.' || p[j] === s[i]);
if (j + 1 < n && p[j + 1] === '*') dp[i][j] = dp[i][j + 2] || (first && dp[i + 1][j]);
else dp[i][j] = first && dp[i + 1][j + 1];
}
}
return dp[0][0];
}
bool isMatch(string s, string p) {
int n = p.size();
auto closure = [&](vector<bool>& set) {
for (int j = 0; j + 1 < n; j++) {
if (set[j] && p[j + 1] == '*') set[j + 2] = true;
}
};
vector<bool> states(n + 1, false);
states[0] = true;
closure(states);
for (char c : s) {
vector<bool> next(n + 1, false);
for (int j = 0; j < n; j++) {
if (!states[j] || (p[j] != '.' && p[j] != c)) continue;
if (j + 1 < n && p[j + 1] == '*') next[j] = true;
else next[j + 1] = true;
}
closure(next);
states = next;
}
return states[n];
}
public boolean isMatch(String s, String p) {
int n = p.length();
boolean[] states = new boolean[n + 1];
states[0] = true;
closure(states, p);
for (char c : s.toCharArray()) {
boolean[] next = new boolean[n + 1];
for (int j = 0; j < n; j++) {
if (!states[j] || (p.charAt(j) != '.' && p.charAt(j) != c)) continue;
if (j + 1 < n && p.charAt(j + 1) == '*') next[j] = true;
else next[j + 1] = true;
}
closure(next, p);
states = next;
}
return states[n];
}
private void closure(boolean[] set, String p) {
int n = p.length();
for (int j = 0; j + 1 < n; j++) {
if (set[j] && p.charAt(j + 1) == '*') set[j + 2] = true;
}
}
def is_match(s, p):
n = len(p)
def closure(st):
for j in range(n - 1):
if st[j] and p[j + 1] == '*': st[j + 2] = True
states = [False] * (n + 1)
states[0] = True
closure(states)
for c in s:
nxt = [False] * (n + 1)
for j in range(n):
if not states[j] or (p[j] != '.' and p[j] != c): continue
if j + 1 < n and p[j + 1] == '*': nxt[j] = True
else: nxt[j + 1] = True
closure(nxt)
states = nxt
return states[n]
function isMatch(s: string, p: string): boolean {
const n = p.length;
const closure = (set: boolean[]): void => {
for (let j = 0; j + 1 < n; j++) {
if (set[j] && p[j + 1] === '*') set[j + 2] = true;
}
};
let states = new Array<boolean>(n + 1).fill(false);
states[0] = true;
closure(states);
for (const c of s) {
const next = new Array<boolean>(n + 1).fill(false);
for (let j = 0; j < n; j++) {
if (!states[j] || (p[j] !== '.' && p[j] !== c)) continue;
if (j + 1 < n && p[j + 1] === '*') next[j] = true;
else next[j + 1] = true;
}
closure(next);
states = next;
}
return states[n];
}