Regular Expression Matching

本贴最后更新于 2492 天前,其中的信息可能已经时移世异

题目描述

Implement regular expression matching with support for '.' and '*'.

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

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

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:
isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "a*") → true
isMatch("aa", ".*") → true
isMatch("ab", ".*") → true
isMatch("aab", "c*a*b") → true

解题思路

和牛客网的正则表达式匹配是一道题。
这里看到 LeetCode 上有利用动态规划的方法,主要思想是利用一个二维数组 memo,保存已经对比过的字符串 i 和匹配串 j 位,减小了时间复杂度。

  • 如果 memo[i][j]不为空,说明字符串 i 位与匹配串 j 位已经匹配过,直接返回匹配结果就可以;
  • 如果匹配串已经匹配完:
    • 如果字符串匹配完,返回 true;
    • 否则返回 false;
  • 正常匹配会有以下情况:
    • 如果匹配串下一个字符不为‘*’:
      • 如果字符串 i 与匹配串 j 不相等,则 memo[i][j]=false;
      • 若相等,继续下一位匹配;
    • 如果下一位字符为‘*’:
      • 匹配串后移两位(相当于匹配串本位出现次数为 0),或者在 i 与 j 相等情况下字符串后移一位(相当于匹配串本位出现一至多次),任意一种匹配成功都可以返回 true。

附在这里。

代码

enum Result {
    TRUE, FALSE
}

class Solution {
    Result[][] memo;
        
    public boolean isMatch(String text, String pattern) {
        memo = new Result[text.length() + 1][pattern.length() + 1];
        return dp(0, 0, text, pattern);
    }
    
    public boolean dp(int i, int j, String text, String pattern) {
        if (memo[i][j] != null) {
            return memo[i][j] == Result.TRUE;
        }
        boolean ans;
        if (j == pattern.length()){
            ans = i == text.length();
        } else {
            boolean first_match = (i < text.length() && 
                                   (pattern.charAt(j) == text.charAt(i) ||
                                    pattern.charAt(j) == '.'));

            if (j + 1 < pattern.length() && pattern.charAt(j+1) == '*'){
                ans = (dp(i, j+2, text, pattern) || 
                       first_match && dp(i+1, j, text, pattern));
            } else {
                ans = first_match && dp(i+1, j+1, text, pattern);
            }
        }
        memo[i][j] = ans ? Result.TRUE : Result.FALSE;
        return ans;
    }
}
  • 算法
    428 引用 • 254 回帖 • 24 关注
  • LeetCode

    LeetCode(力扣)是一个全球极客挚爱的高质量技术成长平台,想要学习和提升专业能力从这里开始,充足技术干货等你来啃,轻松拿下 Dream Offer!

    209 引用 • 72 回帖

相关帖子

欢迎来到这里!

我们正在构建一个小众社区,大家在这里相互信任,以平等 • 自由 • 奔放的价值观进行分享交流。最终,希望大家能够找到与自己志同道合的伙伴,共同成长。

注册 关于
请输入回帖内容 ...