【题目

匹配通配符*,?,DP动态规划,重点是*的两种情况

想象成两个S、P长度的字符串,P匹配S。

S中不会出现通配符。

【条件】

(1)P=null,S=null,TRUE

(2)P=null,S!=null,P必然无法匹配S,FALSE。

(3)P[i]=“*” 的TRUE/FALSE状态等价于P[i-1]

(4)考虑*两种情况,ab, ab*(*=null)、abcd, ab*(*=cd)

【参考】

The most confusing part for me is how to deal with '*'. At first I couldn't figure out why the condition would be (dp[i-1][j] == true || dp[i][j-1] == true). Hope detailed DP description below helps!

 

  • dp[i][j]: true if the first i char in String s matches the first j chars in String p
  • Base case:
    • origin: dp[0][0]: they do match, so dp[0][0] = true
    • first row: dp[0][j]: except for String p starts with *, otherwise all false
    • first col: dp[i][0]: can't match when p is empty. All false.
  • Recursion:
    • Iterate through every dp[i][j]
    • dp[i][j] = true:
      • if (s[ith] == p[jth] || p[jth] == '?') && dp[i-1][j-1] == true 
      • elif p[jth] == '*' && (dp[i-1][j] == true || dp[i][j-1] == true) 
        -for dp[i-1][j], means that * acts like an empty sequence. 
        eg: ab, ab*
        -for dp[i][j-1], means that * acts like any sequences
        eg: abcd, ab*
  • Start from 0 to len
  • Output put should be dp[s.len][p.len], referring to the whole s matches the whole p

Be careful about the difference of index i,j in String (0 to len-1) and the index i, j in dp (0 to len)!


 

Below is my AC code in Java:

 

public boolean isMatch(String s, String p) {
        if(s == null || p == null) return false;
        int sLen = s.length();
        int pLen = p.length();
        boolean[][] dp = new boolean[sLen + 1][pLen + 1];
        
        // Base cases:
        dp[0][0] = true;
        for(int i = 1; i <= sLen; i++){
            dp[i][0] = false;
        }       
        for(int j = 1; j <= pLen; j++){
            if(p.charAt(j-1) == '*'){
                dp[0][j] = dp[0][j-1];
            }            
        }
        
        // Recursion:
        for(int i = 1; i <= sLen; i++){
            for(int j = 1; j <= pLen; j++){
                if((s.charAt(i-1) == p.charAt(j-1) || p.charAt(j-1) == '?') && dp[i-1][j-1])
                    dp[i][j] = true;
                else if (p.charAt(j-1) == '*' && (dp[i-1][j] || dp[i][j-1]))
                    dp[i][j] = true;
            }
        }
        return dp[sLen][pLen];
    }
 posted on 2018-10-31 19:16  alau  阅读(129)  评论(0编辑  收藏  举报