leetcode #44 in cpp

来源:互联网 发布:面板数据到底是怎样的 编辑:程序博客网 时间:2024/06/05 18:54

Solution: 

We use DP to solve this problem. 

Initialize bool dp[pattern length + 1][ s length + 1] = {false}, where dp[i][j] = true if pattern[0....i-1] matches s[0....j-1] and false otherwise. 

The reason we use pattern length + 1 and s length + 1is that during iteration we would always determine d[i][j] by d[i-1][j-1] or d[i][j-1] or d[i-1][j]. If we start i,j from 0 then i-1 and j-1 would be out of bound. It is convenient to have one more row and one more column, with dp[0][j] means if the head of pattern ""(empty string) matches s[0...j-1] and dp[i][0] means if the head of string ""(empty string) matches pattern[0....i-1] .For example, compare pattern = "abcd", s = "ab*c"
 ""abcd""10000a0    b0    *0    d0    Figure 1.

Next we find how to get dp[i][j] from other entries. 

Suppose we are now to get dp[i][j]. It should be related to what p[i-1] and s[j-1] is. 

string:s[0............j-2]s[j-1]

pattern:p[0.............i-2]p[i-1]

There are three cases: 

1. p[i-1] == '*':

In this case, pattern[0....i-1] matches s[0....j-1] if: 

1.1 p[0.....i-2] matches s[0....j-1]. (since p[i-1] can match an empty string) 

1.2. p[0....i-2] matches s[0....j-2]. (since p[i-1] can match any character or string and thus it matches s[j-1])

dp[i][j] = dp[i-1][j] || dp[i-1][j-1]

2. p[i-1] == '?': Note that '?' could not match an empty string. It can just match one character

In this case, pattern[0....i-1] matches s[0....j-1] if: 

2.1 p[0....i-2] matches s[0....j-2]. (since p[i-1] matches s[j-1] since '?' could match any character)

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

3. p[i-1] != '?' and p[i-1] != '*': 

In this case, pattern[0....i-1] matches s[0....j-1] if: 

3.1 p[0....i-2] matches s[0....j-2] and p[i-1] == s[j-1].
dp[i][j] = dp[i-1][j-1] && p[i-1] == s[j-1];

Up to now we have all equations. These equations could finally calculate [pattern length + 1][string length + 1]. Before we calculate these equations, we need to get the boundary conditions, which are dp[0][0...s length] and dp[0....pattern length][0], the first row and first column in the Figure 1.
We know that dp[0][0] = 1 since ""(empty string) matches "". 
We also know that dp[0][1....s length] = 0 (since empty string at the head of the pattern cannot match any s[0...i], i in range of[0,s length-1])
How about dp[1....pattern length][0]? 
For example:  If we have pattern = "***a", string = "a";
 ""a""10*1 *1 ?1 a0 We could see that if p[i-1] != '*', dp[i][0] = 0(since '?' or other characters can never match an empty string). 
And if p[i-1] == '*', dp[i][0] = dp[i-1][0]( if p[0...i-2] cannot match an empty string, it means there is an non-'*' string in p[0....i-2] and thus p[0...i] cannot match an empty string anymore. If p[0....i-2] can match an empty string, p[0...i-1] can also match an empty string since p[i-1] matches an empty string)

As we have initialization and state equations. We could solve the problem by returning dp[pattern length][string length] which means if pattern[0....end] matches string[0....end].

Code: 

 
class Solution {public:    bool isMatch(string s, string p) {        vector<vector<bool>> dp(p.length()+1,vector<bool>(s.length()+1));        dp[0][0] = true;        for(int i = 1; i < p.length()+1; i ++)            if(p[i-1] == '*'){                dp[i][0] = dp[i-1][0];            }        for(int i = 1; i < p.length()+1; i ++){            for(int j = 1; j < s.length()+1; j ++){                if(p[i-1] == '?' ||  p[i-1] == s[j-1]){                    dp[i][j] = dp[i-1][j-1];                                    }else if(p[i-1] == '*' &&(dp[i-1][j-1]||dp[i-1][j]||dp[i][j-1]))                    dp[i][j] = true;            }        }        return dp[p.length()][s.length()];            }};


0 0
原创粉丝点击