1. dp[i][j] = can match or not using s[0, i - 1] and p[0, j - 1]
2. induction rule:
if p[j - 1] is letter
if p[j - 1] == s[i - 1] || s[i - 1] == ?: dp[i - 1][j - 1]
if p[j - 1] is ?
dp[i - 1][j - 1]
if p[j - 1] is *
dp[i][j] = dp[i - 1][j] || dp[i][j - 1]
3. fill in order
left -> right up -> down
4. base case
dp[0][0] = true, dp[0][j] = p[i - 1] == * ? dp[0][i - 1] : false
5. result
dp[n][m]
time: O(m * n)
space: O(m * n)