LeetCode 10 正则表达式匹配(难度:Hard)

今天药忘吃喽~ 2022-03-06 14:56 211阅读 0赞

题意:正则表达式匹配

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.

  1. '.' Matches any single character.
  2. '*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.

Example 1:

  1. Input:
  2. s = "aa"
  3. p = "a"
  4. Output: false
  5. Explanation: "a" does not match the entire string "aa".

Example 2:

  1. Input:
  2. s = "aa"
  3. p = "a*"
  4. Output: true
  5. Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".

Example 3:

  1. Input:
  2. s = "ab"
  3. p = ".*"
  4. Output: true
  5. Explanation: ".*" means "zero or more (*) of any character (.)".

Example 4:

  1. Input:
  2. s = "aab"
  3. p = "c*a*b"
  4. Output: true
  5. Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".

Example 5:

  1. Input:
  2. s = "mississippi"
  3. p = "mis*is*p*."
  4. Output: false

正则表达式匹配,关键就是匹配这俩字。首先,有两个对象,比较这两个对象,只有一模一样才叫做匹配。从 note 看,

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.

输入串s 可为空 或者 只包含小写字母 (a-z)

样品 p 可为空 或者 包含唯一一个小写字母(a-z)和 ‘ . ‘ ‘ * ‘ 这两个特殊字符

‘.’ Matches any single character. ‘.’ 可变成任意一个单字符

‘*‘ Matches zero or more of the preceding element. ‘*‘ 可让在其最前面的一个字符重复 0 或 n 次 (0 次表示其前一个字符消失)

第一种解法: 递归

  1. package pers.leetcode;
  2. /**
  3. * LeetCode 10 正则表达式匹配
  4. * 难度: Hard
  5. *
  6. * @author 朱景辉
  7. * @date 2019/3/21 9:49
  8. */
  9. public class RegularExpressionMatching {
  10. public static void main(String[] args) {
  11. String s = "ab";
  12. String p = ".*c";
  13. System.out.println("是否匹配: " + isMatch(s, p));
  14. }
  15. public static boolean isMatch(String text, String pattern){
  16. // 先处理特殊情况,pattern 为空的情况下,text为空返回true,否则返回false
  17. if (pattern.isEmpty()){
  18. return text.isEmpty();
  19. }
  20. // 首先比较双方第一个字符是否相同,2 种情况
  21. // 1. 两者第一个字符相同
  22. // 2. pattern 的第一个字符是 '.'
  23. boolean first_match = (!text.isEmpty() && (pattern.charAt(0) == text.charAt(0) || pattern.charAt(0) == '.'));
  24. // 递归处理两种情况
  25. // 1. pattern长度大于等于 2 ,且第 2 个字符为'*'
  26. // 2. 要么 pattern 长度为1,要么长度大于等于 2,但第二个字符不为 '*'
  27. if (pattern.length() >= 2 && pattern.charAt(1) == '*'){
  28. // 这里返回也有两种情况
  29. // 1. '*' 将其前一个字符置空,再从 text 的第一个字符 与 pattern 的第三个字符匹配
  30. // 2. '*' 目前重复 1 次, 与 text 第一个字符匹配到了,再用 text 的第二个字符 与 pattern 的第一个字符匹配
  31. return (isMatch(text, pattern.substring(2)) || (first_match && isMatch(text.substring(1), pattern)));
  32. }else {
  33. // 只有双方第一个字符相同 且 剩余字符匹配 才返回 true
  34. return first_match && isMatch(text.substring(1), pattern.substring(1));
  35. }
  36. }
  37. }

运行结果:

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMzc4ODUz_size_16_color_FFFFFF_t_70

第二种解法:动态规划。。。现在不想写了

2019/9/22 补上

  1. /**
  2. * 动态规划
  3. *
  4. * @param text 给定字符串
  5. * @param pattern 匹配字符串
  6. * @return 匹配结果
  7. */
  8. public static boolean isMatch2(String text, String pattern){
  9. boolean[][] dp = new boolean[text.length() + 1][pattern.length() +1];
  10. dp[text.length()][pattern.length()] = true;
  11. for (int i = text.length(); i >= 0; i--){
  12. for (int j = pattern.length() - 1; j>= 0; j--){
  13. // 双方最后一个字符是否相同 或者 pattern 最后一个字符为 '.'
  14. boolean first_match = (i < text.length() && (pattern.charAt(j) == text.charAt(i) || pattern.charAt(j) == '.'));
  15. // 1. 从 pattern 倒数第二个字符起, 凡是等于 '*' 的情况
  16. // 2. 不等于 '*'
  17. if (j + 1 < pattern.length() && pattern.charAt(j+1) == '*'){
  18. dp[i][j] = dp[i][j+2] || first_match && dp[i+1][j];
  19. }else {
  20. dp[i][j] = first_match && dp[i+1][j+1];
  21. }
  22. }
  23. }
  24. return dp[0][0];
  25. }

watermark_type_ZmFuZ3poZW5naGVpdGk_shadow_10_text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3FxXzMzMzc4ODUz_size_16_color_FFFFFF_t_70 1

明显的,动态规划比递归快了 N 倍

发表评论

表情:
评论列表 (有 0 条评论,211人围观)

还没有评论,来说两句吧...

相关阅读