Skip to content
AI360Xpert
Beta
Difficulty: Hard2-D Dynamic Programming

Regular Expression Matching

Problem in Plain English

Given a string and a pattern with dot and star operators, decide whether the whole string matches the whole pattern. A dot matches any single character and a star repeats its preceding element zero or more times.

Problem Statement

Given lowercase string s and valid pattern p, return whether the entire string matches the entire pattern. A literal letter matches itself, . matches exactly one character, and * repeats the immediately preceding letter or dot zero or more times. For example, a* can match an empty remainder, one a, or several consecutive a characters.

This is the restricted dot-and-star language: * is not a standalone wildcard, and there are no alternation, grouping, or other operators. Return a boolean; a matching substring alone is insufficient. Example 1 has s = "aa" and p = "a*", so two repetitions cover both characters and return true.

Constraints

  • 1 <= s.length <= 20
  • 1 <= p.length <= 20
  • s contains only lowercase English letters.
  • p contains only lowercase English letters, . and *.
  • Every * has a valid preceding character to repeat.

Examples

Example 1

Input
s = "aa", p = "a*"
Output
true

Use a* twice: the first a consumes one repetition and the second consumes another. Then stop repeating. Both string and pattern are exhausted, so the full match is true.

Example 2

Input
s = "aa", p = "a"
Output
false

The single literal a consumes only the first character. A second a remains after the pattern ends, so a prefix match does not count and the answer is false.

Example 3

Input
s = "ab", p = ".*"
Output
true

Repeat the dot twice. Its first use matches a and its second matches b; each dot use consumes exactly one character. Stopping afterward covers the whole string and returns true.

Example 4

Input
s = "aab", p = "c*a*b"
Output
true

Use zero copies of c, two copies of a, and then the literal b. The initial c* disappears completely; requiring at least one copy would wrongly reject this valid full match.

Intuition

A star makes the repetition count uncertain: in Example 1, a* could take zero, one, or two copies, but only two cover all of "aa". Resolve that uncertainty with two exhaustive choices: skip the whole atom-star pair, or consume one matching character and leave that pair available. Ordinary letters and dots consume exactly one character. Different repetition choices can reach the same pair of positions; a table stores each pair once instead of exploring its continuations again.

Approaches

Brute Force Recursion

Solution Details

Reveal Brute Force Recursion: intuition, complexity, and code

Hints

Hint 1
A matching prefix is insufficient: what must be true when the pattern ends?
Hint 2
For an atom followed by a star, separate zero copies from at least one copy. After taking one copy, why should the same atom-star pair remain available?
Hint 3
Use a pair of indices as the state. For the table, let prefix lengths include zero; a star reads two columns left and, for a matching character, one row above.

Edge Cases

  • s = "a", p = "ab*" is true: the final b* uses zero copies after the literal a consumes the string.
  • s = "b", p = "a*b" is true even though the first atom does not match; the zero-copy branch must remain available.
  • s = "a", p = "." is true, but s = "ab", p = "." is false: a dot consumes exactly one character.
  • s = "ab", p = ".*c" is false: the final literal c cannot disappear. Greedily consuming the whole string with .* does not finish the pattern.
  • s = "aaa", p = "a*a" is true: leave one a for the final literal rather than committing greedily to a repetition count.
  • Although published inputs are nonempty, recursion reaches empty suffixes and the table needs an empty-prefix row. Defensive calls with s = "", p = "a*b*" return true; with s = "a", p = "" they return false.

Common Mistakes and Interview Tips

  • Treating * as the glob wildcard that matches arbitrary characters. Here it repeats only its preceding atom, which may itself be a dot.
  • Consuming one star repetition and then advancing past the pair prevents further repetitions. Recursion keeps j fixed; the table reads above in the same column.
  • Allowing a star to consume without checking the preceding atom matches, or requiring at least one copy and losing the zero-copy branch.
  • Returning true as soon as one side ends. Remaining starred pairs may disappear, but remaining literal atoms or string characters cannot.
  • Skipping the empty-string initialization, or copying one column left for zero repetitions instead of removing both atom and star.
  • Aliasing all Python or JavaScript table rows: a write to one row then corrupts other prefix states. Allocate each row independently.
  • Interview tip: explain both star predecessors and their meanings before writing the recurrence. The uncached recursion has small depth but can still branch exponentially on a late mismatch; the table has only one state per prefix pair.

Key Takeaway

When an operator can use zero copies or consume another character without moving past itself, separate those cases explicitly. Recording both string and pattern positions turns repeated matching paths into a finite table of shared states.