LeetCode Regular Expression Matching

来源:互联网 发布:js post 跨域解决方案 编辑:程序博客网 时间:2024/06/11 09:27

问题网址:https://leetcode.com/problems/regular-expression-matching/description/

问题描述:
实现正则表达式匹配,支持’。’ 和’*’。

'.' 匹配任何单个字符。'*'匹配零个或多个前面的元素。匹配应覆盖整个输入字符串(不是部分)。函数原型应该是:bool isMatch(const char * s,const char * p)一些例子:isMatch(“aa”,“a”)→falseisMatch(“aa”,“aa”)→trueisMatch(“aaa”,“aa”)→falseisMatch(“aa”,“a *”)→trueisMatch(“aa”,“。*”)→trueisMatch(“ab”,“。*”)→trueisMatch(“aab”,“c * a * b”)→true

下面讨论一种方法
方法1:递归

直觉

如果没有Kleene星(正则表达式的*通配符),问题会更容易 - 我们只需从左到右检查文本的每个字符是否与模式匹配。

当星星出现时,我们可能需要检查文本的许多不同的后缀,看它们是否与模式的其余部分相匹配。 递归解决方案是一种直接的方式来表示这种关系。

算法

没有Kleene明星,我们的解决方案将如下所示:
如果模式中存在星号,它将位于第二个位置\ text {pattern [1]} pattern [1]。 那么,我们可能会忽略这部分模式,或者删除文本中的匹配字符。 如果我们在这些操作之后剩余的字符串匹配,则匹配初始输入。

class Solution {    public boolean isMatch(String text, String pattern) {        if (pattern.isEmpty()) return text.isEmpty();        boolean first_match = (!text.isEmpty() &&                                (pattern.charAt(0) == text.charAt(0) || pattern.charAt(0) == '.'));        if (pattern.length() >= 2 && pattern.charAt(1) == '*'){            return (isMatch(text, pattern.substring(2)) ||                     (first_match && isMatch(text.substring(1), pattern)));        } else {            return first_match && isMatch(text.substring(1), pattern.substring(1));        }    }}

另一种方法:
方法#2:动态规划

直觉

由于问题具有最佳的子结构,缓存中间结果是很自然的。 我们问这个问题\ text {dp(i,j)} dp(i,j):does \ text {text [i:]} text [i:] and \ text {pattern [j:]} pattern [j: ] 比赛? 我们可以用涉及较小字符串的问题的答案来描述我们的答案。

算法

除了因为调用只会匹配(text [i:],pattern [j:]),我们使用\ text {dp(i,j)} dp( 我,j)来处理这些调用,节省了我们昂贵的字符串构建操作,并允许我们缓存中间结果。

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;    }}
原创粉丝点击