题意

image.png

图示:

1. *代表一个字符的情况

1 (6).png

2. * 代表一个字符的情况

2 (1).png

  1. * 代表多个字符的情况

3.png

解题思路:

  1. 思路:
  2. 状态定义:dp[i][j] 表示 s 的前 i 个字符是否能被 p 的前 j 个字符匹配
  3. 转移方程:
  4. * sc = s[i - 1] pc = p[j - 1]
  5. 1. sc == pc|| pc == '.'
  6. 1.1 '.'是万能字符,可以直接让'.'等于s[i]处的字符
  7. 即:dp[i][j] = dp[i-1][j-1];
  8. 2. sc != pc || pc == '*' 3种情况考虑
  9. 2.1 '*'代表0个字符
  10. 例子:s:aab, p:aabb*,重复0b,相当于直接删去j-1(*)和j-2(b),最终要比较的是s(0...i-1)~p(0...j-3)
  11. 即:dp[i][j] = dp[i][j-2]
  12. 2.2 '*'代表1个字符
  13. 例子:s:aab, p:aab* (取1个字符,相当于去掉p[j-1]),只需要比较s(0...i-1)~p(0...j-2)
  14. 即:dp[i][j] = dp[i][j-1]
  15. 2.2 '*'代表多个字符
  16. 例子:saab, paab* => s:aab, paab*b 因为s的最后一个字符b等于p的最后一个字符,可以相互抵消,所以只需要比较 s(0...i-2)~p(0...j-1)即aaaab*比较
  17. 即:dp[i][j] = dp[i-1][j]
  18. 3. sc != pc : i,j处是普通字符时,自然不相等
  19. 即:dp[i][j] = false
  1. 初始化:
  2. 1. s,p都为空串时则相匹配=》dp[0,0] = true;
  3. 2. s不为空串,模式串p为空串时=》dp[i,0] = false, i >= 1
  4. 3. s为空串,模式串p不为空串时,需要考虑p为*号的情况
  5. 3.1 如果p最后一个字符p[j-1] == '*',则可以用*把他前面字符重复0次,即消除前面字符,推出=》dp[0, j] = dp[0, j - 2]
  6. 3.2 如果p最后一个字符p[j-1] != '*',则不相等,即dp[0, j] = false

PHP代码实现:

  1. class Solution {
  2. function isMatch($s, $p) {
  3. //if ($s == null || $p == null) return false;
  4. $m = strlen($s);
  5. $n = strlen($p);
  6. $dp = array_fill(0, $m + 1, array_fill(0, $n + 1, false));
  7. $dp[0][0] = true;
  8. for ($i = 1; $i <= $m; $i++) $dp[$i][0] = false;
  9. //s为空串,p不是空串的初始化
  10. for ($j = 1; $j <= $n; $j++) {
  11. //$p[$j - 1] == '*',消除j前面的字符
  12. if ($p[$j - 1] == '*') $dp[0][$j] = $dp[0][$j - 2];
  13. else $dp[0][$j] = false;
  14. }
  15. for ($i = 1; $i <= $m; $i++) {
  16. for ($j = 1; $j <= $n; $j++) {
  17. $sc = $s[$i - 1];
  18. $pc = $p[$j - 1];
  19. if ($this->isEqual($sc, $pc)) {
  20. $dp[$i][$j] = $dp[$i - 1][$j - 1];
  21. } else if ($pc == '*') {
  22. $preChar = $p[$j - 2];
  23. if ($this->isEqual($sc, $preChar)) {
  24. $dp[$i][$j] = $dp[$i][$j - 2] || $dp[$i][$j - 1] || $dp[$i - 1][$j];
  25. } else $dp[$i][$j] = $dp[$i][$j - 2];
  26. } else {
  27. $dp[$i][$j] = false;
  28. }
  29. }
  30. }
  31. return $dp[$m][$n];
  32. }
  33. function isEqual($sc, $pc) {
  34. return $sc == $pc || $pc == '.';
  35. }
  36. }

GO代码实现: