剑指 Offer 19. 正则表达式匹配

这题好难。自己没想到用动态规划,敲了很久,敲出了可以通过400个测试点的代码,还是有一些情况没有考虑到。不舍得删,记录一下。对输入用例

"aaa"
"ab*a*c*a"

不能给出正确答案

class Solution {
    public boolean isMatch(String s, String p) {
        char[] ss=s.toCharArray();
        char[] pp=p.toCharArray();
        int i=ss.length-1;
        int j=pp.length-1;

        boolean label=false;//false表示没遇到*,或者说是*的作用无效时
        while(i>=0&&j>=0){
            if(ss[i]==pp[j]||pp[j]=='.')//匹配时
            {
                i--;
                if(!label)//*没有发挥作用时
                    j--;
            }
            else if(label){//第一次不匹配时,if有*起作用
                label=false;
                j--;
            }
            else if(pp[j]=='*'){
                label=true;//label发挥作用,j-1后j不能再动,除非失效了
                j--;
            }
            else//既没有*号起作用,又不匹配,结束循环
                break;

        }
        if(i>=0)
            return false;
        else {//j>=0
            while(j>=0){
                if(label){
                    label=false;
                    j--;
                }
                else if(pp[j]=='*'){
                    label=true;
                    j--;
                }
                else//label失效且不是*
                return false;


            }

        }
     return true;
}

}

看别人的思路,总算敲出了正确代码:

class Solution {
    public boolean isMatch(String s, String p) {
        char[] ss=s.toCharArray();
        char[] pp=p.toCharArray();
        int m=ss.length;
        int n=pp.length;

        boolean[][] dp=new boolean[m+1][n+1];//问如何快速初始化二维数组?二维数组会默认初始化吗?
        dp[0][0]=true;
        for(int i=2;i<n+1;i++)
            dp[0][i]=pp[i-1]=='*'&&dp[0][i-2];

        for(int i=1;i<m+1;i++){//i表示处理s串的前i个字符(i必须!=0)
            for(int j=1;j<n+1;j++){
                if(pp[j-1]==ss[i-1]||pp[j-1]=='.')
                    dp[i][j]=dp[i-1][j-1];
                if(pp[j-1]=='*'){
                    if(pp[j-2]==ss[i-1]||pp[j-2]=='.')//输入要保证pp第一个字符不是*
                        dp[i][j]=dp[i-1][j]||dp[i][j-2];//ss的该字符是多个连续相同字符的最后一个还是当前唯一一个与之匹配的都这样处理
                                                        //也要包含*和前面的字符要去掉的情况,所以要加个||
                    else
                        dp[i][j]=dp[i][j-2];//不相等的话,去掉*和前面的字符
                }
            }
        }
        return dp[m][n];
    }

}
posted @ 2021-03-14 20:50  wsshub  阅读(40)  评论(0)    收藏  举报