Problem Statement
Given an input string s and a pattern p, implement regular expression matching with support for '.' and '*' where: '.' Matches any single character. '*' Matches zero or more of the preceding element. The matching should cover the entire input string (not partial). 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 preceding 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 (.)". Constraints: 1 <= s.length <= 20 1 <= p.length <= 20 s contains only lowercase English letters. p contains only lowercase English letters, '.', and '*'. It is guaranteed for each appearance of the character '*', there will be a previous valid character to match.
Java Solution
You can solve this problem using dynamic programming. Here’s a Java solution for the given problem:
public class RegularExpressionMatching {
public static boolean isMatch(String s, String p) {
int m = s.length();
int n = p.length();
// dp[i][j] represents whether the first i characters in s match the first j characters in p
boolean[][] dp = new boolean[m + 1][n + 1];
// Empty pattern matches empty string
dp[0][0] = true;
// Handle patterns with '*'
for (int j = 1; j <= n; j++) {
if (p.charAt(j - 1) == '*') {
dp[0][j] = dp[0][j - 2];
}
}
// Build the dp array
for (int i = 1; i <= m; i++) {
for (int j = 1; j <= n; j++) {
char sChar = s.charAt(i - 1);
char pChar = p.charAt(j - 1);
if (pChar == sChar || pChar == '.') {
dp[i][j] = dp[i - 1][j - 1];
} else if (pChar == '*') {
dp[i][j] = dp[i][j - 2] || (dp[i - 1][j] && (sChar == p.charAt(j - 2) || p.charAt(j - 2) == '.'));
}
}
}
return dp[m][n];
}
public static void main(String[] args) {
// Example 1
System.out.println(isMatch("aa", "a")); // Output: false
// Example 2
System.out.println(isMatch("aa", "a*")); // Output: true
// Example 3
System.out.println(isMatch("ab", ".*")); // Output: true
}
}
In this solution, the dp
array is used to store whether the first i
characters in string s
match the first j
characters in pattern p
. The algorithm iterates through the characters in s
and p
, updating the dp
array based on the matching conditions. The final result is stored in dp[m][n]
, where m
and n
are the lengths of the input strings s
and p
. The examples in the main
method demonstrate the usage of the function with the provided test cases.
Python Solution
def isMatch(s, p):
m, n = len(s), len(p)
# dp[i][j] represents whether the first i characters in s match the first j characters in p
dp = [[False] * (n + 1) for _ in range(m + 1)]
# Empty pattern matches empty string
dp[0][0] = True
# Handle patterns with '*'
for j in range(1, n + 1):
if p[j - 1] == '*':
dp[0][j] = dp[0][j - 2]
# Build the dp array
for i in range(1, m + 1):
for j in range(1, n + 1):
s_char = s[i - 1]
p_char = p[j - 1]
if p_char == s_char or p_char == '.':
dp[i][j] = dp[i - 1][j - 1]
elif p_char == '*':
dp[i][j] = dp[i][j - 2] or (dp[i - 1][j] and (s_char == p[j - 2] or p[j - 2] == '.'))
return dp[m][n]
# Example 1
print(isMatch("aa", "a")) # Output: False
# Example 2
print(isMatch("aa", "a*")) # Output: True
# Example 3
print(isMatch("ab", ".*")) # Output: True
This Python code follows the same dynamic programming approach as the Java solution. The isMatch
function returns True
if the entire input string s
matches the pattern p
, and False
otherwise. The examples at the end demonstrate the usage of the function with the provided test cases.