zoukankan      html  css  js  c++  java
  • LeetCode10.正则表达式匹配

      本题为困难题,看了很久才看懂,题目如下:

      注意,*和前面的字符是一个整体,如果不进行匹配的话两个字符都可以去掉。

      思路:1.两个序列进行匹配,而且它们还有递推的关系,都应该考虑使用动态规划

         2.动态规划创建二维数组dp[i][j],但要注意应该比两个字符串长度多出一位,i和j为0表示空的情况,主要目的是为了方便创建dp数组的初始值

         3.具体办法:

            3.1.初始化,dp[0][0]=true,dp[0][j](j!=0)=false;很好理解

            3.2.当遍历到i和j时,两者相等或p遍历到"."的位置,可以匹配,那么如果前一位也能匹配的话就为true

            3.3.当j指向的是*时:分情况讨论:

              3.3.1.s[i]!=p[j-1],即*代表的字符不能与相应的i位匹配,那应该考虑去掉*和前面的字符,即匹配0次的情况,如下:

              

              这个时候dp[i][j]=dp[i][j-2].

              3.3.2.此时若s[i]==p[j-1],即s[i]可以和*前面的字符匹配,这个时候就会出现到底应该匹配几次的问题,例如s="caaab",p="ca*ab",此时i=j=3,我们的动态规划是从前往后遍历的,只能由前面的状态来推导,我们可以把i往前移动,一直到s[i]不等于p[j-1],如果这里匹配不上的话,那么之后的匹配不可能成功,反过来,dp[i][j]的状态完全可以前推到s[i]不等于p[j-1]时的状态,由其决定。假设s[i1]!=p[j-1],而i1到i之间的所有位都等于p[j-1]的话,从i1到j之间所有状态都由dp[i1][j]决定,所以dp[i][j]完全可以由dp[i-1][j]来决定,就算i-1和i位相等,那么最终状态肯定也是一样的。故dp[i][j]=dp[i-1][j]。如下:

                      

         代码如下:

        

    class Solution {
        public boolean isMatch(String s, String p) {
            int m=s.length();
            int n=p.length();
            boolean[][] dp=new boolean[m+1][n+1];
            dp[0][0]=true;
            for(int i=0;i<=m;i++){
                for(int j=1;j<=n;j++){
                    if(p.charAt(j-1)=='*'){
                        dp[i][j]=dp[i][j-2];
                        if(match(s,p,i,j-1))
                            dp[i][j]=dp[i][j]||dp[i-1][j];
                    }else{
                        if(match(s,p,i,j))
                            dp[i][j]=dp[i-1][j-1];
                    }
                }
            }
            return dp[m][n];
        }
        boolean match(String s,String p,int i,int j){
            if(i==0) return false;
            return s.charAt(i-1)==p.charAt(j-1)||p.charAt(j-1)=='.';
        }
    }

       

  • 相关阅读:
    c/c++ 网络编程 getaddrinfo 函数
    c/c++ 网络编程 bind函数
    c/c++ socket API 调用后的错误判断 perror errno
    python基础-面向对象编程之反射
    彻底理解Future模式
    Java并发编程:Callable、Future和FutureTask
    java异步调用方法
    理解ThreadLocal
    ReentrantReadWriteLock读写锁
    java锁优化
  • 原文地址:https://www.cnblogs.com/lzjdsg/p/14660803.html
Copyright © 2011-2022 走看看