[leetcode]Regular Expression Matching

Regular Expression Matching

题意:实现这个所谓的正则表达式匹配

           .可以匹配任何一个单独的char,

      *可以让*之前的符号变成0个,或者任意多个

对给出样例进行解释:

isMatch("aa","a") → false      a只能匹配一个a,剩余一个a无法匹配

isMatch("aa","aa") → true      每a都有一个对应a

isMatch("aaa","aa") → false    有一个a无法被匹配

isMatch("aa", "a*") → true     a*可以是空,也可以是a也可以是aa,也可以是任意多个a

isMatch("aa", ".*") → true     .*可以是0个,或者任意多个.

isMatch("ab", ".*") → true      同上

isMatch("aab", "c*a*b")→ true  c*可以是0个c,就是什么都不匹配,a*匹配aa,b匹配b

 

解法:

         DP解法

         F[i][j]代表s的前i个字符与p的前j个字符是否匹配,特别说明f[0][0]自然是true,当i>0时,f[0][i]只有i是*,i-1不是*,并且f[0][i-2]是true时,才为true。

         当i大于0时,对于所有的f[i][0],都为false。

         当计算f[i][j]时,若p的第j位为.,则f[i][j]=f[i-1][j-1]

                                        若p的第j位为字母,若p的第j位与s的第i位相同,f[i][j]=f[i-1][j-1],否则f[i][j]=false;

                                        若p的第j位为*,如果第j-1位为*,f[i][j]=false;

                                                                               如果第j-1位为., 若f[0][j-2]到f[i][j-2]有一个true,f[i][j]=true;

                                                                                    如果第j-1位为字母,若f[i][j-2]为true,f[i][j]=true

                                                                                                                            若f[k-1][j-2]为true,k<=I,并且s的第k到i位都为p的第j位,则f[i][j]=true

         返回f[n.length()][m.length()]

         算法平均情况复杂度为O(n*m),当出现较多*时,会退化到O(n^2*m),例如出现s=”zzzzzzzzzzzz”,p=”x.*.*.*.*.*.*”时,我们利用进行适当剪枝,若f[0][j-2]到f[i][j-2]与f[0][j-1]到f[i][j-1]全为false,则意味着p的前j-1段不可能与结果匹配,这个应该放在对f[x][j]进行整体计算之前进行判断。现在只是理论上认为该算法是O(n^2*m),是否在加入适当剪枝后可以使算法最坏情况有更紧确的上届还不清楚。

public class Solution142 {

         publicboolean isMatch(String s, String p) {

       int n=s.length();

       int m=p.length();       

       boolean[][] f=new boolean[n+1][m+1];

       f[0][0]=true;

       for (int i=1;i<=m;i++){

                if (i>=2){

                          if(p.charAt(i-1)=='*'&&p.charAt(i-1-1)!='*'){

                                   f[0][i]=f[0][i-2];

                          }

                }else{

                          f[0][i]=false;

                }

       }

       for (int i=1;i<=n;i++){

                f[i][0]=false;

                for (int j=1;j<=m;j++){

                          if(p.charAt(j-1)=='.'){

                                   f[i][j]=f[i-1][j-1];

                                   continue;

                          }

                          if(p.charAt(j-1)!='*'){

                                   if(p.charAt(j-1)==s.charAt(i-1)){

                                            f[i][j]=f[i-1][j-1];                                            

                                   }

                                   continue;

                          }

                          if (j==1){

                                   returnfalse;

                          }

                          if(p.charAt(j-1-1)=='*'){

                                   returnfalse;

                          }

                          if(p.charAt(j-1-1)!='.'){

                                   if(f[i][j-2]){

                                            f[i][j]=true;

                                            continue;

                                   }

                                   charc=p.charAt(j-1-1);

                                   for(int k=i;k>=1;k--){

                                            if(s.charAt(k-1)!=c){

                                                      break;

                                            }

                                            if(f[k-1][j-2]){

                                                      f[i][j]=true;

                                                      break;

                                            }

                                   }

                          }else{

                                   if(f[i][j-2]){

                                            f[i][j]=true;

                                            continue;

                                   }

                                   for(int k=1;k<=i;k++){

                                            if(f[k-1][j-2]){

                                                      f[i][j]=true;

                                                      break;

                                            }

                                   }

                          }

                }

       }

       return f[n][m];

    }

}

 

         递归解法:

                   递归解法的时间复杂度是指数级的,不推荐,不过程序会比DP好写很多。

                   给一个参考链接http://www.cnblogs.com/RazerLu/p/3535641.html

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值