如何优化我的回溯解决方案以匹配正则表达式?

时间:2018-11-17 04:29:47

标签: java regex backtracking

这是我要在LeetCode上解决的问题:

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 letters a-z.
p could be empty and contains only lowercase letters a-z, and characters like ? or *

我已经针对此问题提出了回溯解决方案,

class Solution {

    public boolean isMatch(String s, String p) {
        p = p.replaceAll("\\*+", "*");

        return myIsMatch(s, p);
    }

    public boolean myIsMatch(String s, String p) {
        if(s==null || p == null){
            return false;
        }

        if(p.equals("*")){
            return true;
        }


        int i = 0;
        while(i<s.length() && i<p.length() && s.charAt(i)==(p.charAt(i))){
            i++;

            if(i<s.length() && i>=p.length()){
                return false;
            }
        }

        if(i == s.length() && i == p.length()){
            return true;
        }else if(i != s.length() && i == p.length()){
            return false;
        }else if(i == s.length() && i != p.length()){
            if(p.charAt(i) == '*'){
                return myIsMatch("", p.substring(i+1));    
            }else{
                return false;
            }

        }

        if(p.charAt(i)=='?'){
            if(i+1<s.length() && i+1<p.length()){
                return myIsMatch(s.substring(i+1), p.substring(i+1));    
            }else if(i+1<s.length() && i+1>=p.length()){
                return false;
            }else if(i+1>=s.length() && i+1<p.length()){
                return myIsMatch(s.substring(i+1), p.substring(i+1));
            }else{
                return true;
            }
        }else if(p.charAt(i)=='*'){
            for(int k = i;k<=s.length();k++){
                if(myIsMatch(s.substring(k), p.substring(i+1))){
                    return true;
                }
            }
        }else{
            return false;
        }
        return false;
    }
}

这对于大多数测试用例都很好,除了以下病理情况(程序似乎没有退出),

s = "abbabaaabbabbaababbabbbbbabbbabbbabaaaaababababbbabababaabbababaabbbbbbaaaabababbbaabbbbaabbbbababababbaabbaababaabbbababababbbbaaabbbbbabaaaabbababbbbaababaabbababbbbbababbbabaaaaaaaabbbbbaabaaababaaaabb"

p ="**aa*****ba*a*bb**aa*ab****a*aaaaaa***a*aaaa**bbabb*b*b**aaaaaaaaa*a********ba*bbb***a*ba*bb*bb**a*b*bb"

如何优化代码以处理此类输入?任何帮助,不胜感激!

1 个答案:

答案 0 :(得分:0)

我不认为该程序不会退出。具体来说,您的问题是算法无法针对提供的输入足够快地运行,并且用尽了时间。

回溯解决方案并不是匹配正则表达式的最佳方法。我相信您当前的算法的时间复杂度为O(N ^ 2),但可能更好,也许使用动态编程解决方案。我建议您重新考虑您的方法。

实际上,现在我考虑过,最好的解决方案确实是O(mn)。

Edit:问题是,在回溯解决方案之上,这将导致O(mn)时间复杂性,您还需要遍历辅助函数中的字符串,使其类似于O(n ^ 3)。与其直接修改输入字符串,不如尝试使用记忆来解决问题。