Given an input string (s
) and a pattern (p
), implement wildcard pattern matching with support for '?'
and '*'
.
'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).
The matching should cover the entire input string (not partial).
Note:
s
could be empty and contains only lowercase lettersa-z
.p
could be empty and contains only lowercase lettersa-z
, and characters like?
or*
.
Input: s = "adceb" p = "*a*b" Output: true
题意:
' ?' any single character.
' * ' 0 or more sequence(s).
whether p can match s ?
这题的 ' * '可以像wildcard万能卡一样,代表任意 0个或多个子序列
思路:
跟 10. Regular Expression Matching 的思路很像, 不同的是 ' * ' 在 10. Regular Expression Matching 是依赖于之前的元素。而 ' * '在本题中就直接是任意子序列。
二维dp
p = 0 * a * b 0 T s = "a d c e b"
初始化,
dp[0][0] = true
是否需要预处理第一个row: dp[0][j], 发现当S为空,P为'*' 时,P若取0个subsequnce就可能变成空,此时两个字符串match。需要预处理。
是否需要预处理第一个col:dp[i][0], 发现当P为空,S为任意字符时,肯定不match。不需要预处理,因为默认default就是false。
转移方程,
若两个字符串当前的char相同:
p.charAt(j-1) == s.charAt(i-1) or p.charAt(j-1) == ' ?' 则当前字符match, 那么dp[i][j] 的结果可以直接拿dp[i-1][j-1]的取值
若两个字符串当前的char不同:
1. p.charAt(j-1) == '*' 时,先退后一步先去check一下T/F。若 "*" 可以代表0个subsequnce,dp[i][j] = dp[i][j-1]
2. p.charAt(j-1) == '*' 时,若'*'代表的1 or more subsequnce, 则dp[i][j] = dp[i-1][j] 即S: "abcd" 和 P:"ab * " 是否match, 返回去看 S: "abc" 和 P:"ab * " 是否match
代码:
1 class Solution { 2 public boolean isMatch(String s, String p) { 3 boolean[][] dp = new boolean[s.length() + 1][p.length() + 1]; 4 dp[0][0] = true; 5 for(int j = 1; j <= p.length(); j++){ 6 if(p.charAt(j-1) == '*'){ 7 dp[0][j] = dp[0][j-1]; 8 } 9 } 10 11 for(int i = 1; i <= s.length() ; i++){ 12 for(int j = 1; j <= p.length(); j++){ 13 if(p.charAt(j-1) == s.charAt(i-1) || p.charAt(j-1) == '?' ){ 14 dp[i][j] = dp[i-1][j-1]; 15 }else{ 16 if (p.charAt(j-1) == '*'){ 17 dp[i][j] = dp[i-1][j] || dp[i][j-1]; 18 } 19 } 20 } 21 } 22 return dp[s.length()][p.length()]; 23 } 24 }