Leetcode 44. Wildcard Matching

Wildcard Matching

Wildcard Matching :

給定一個字符串跟pattern,看這個字符串可不可以match pattern,包含“?” 及 ‘*’

“?” 匹配任何單個字符 ( 不包含空字符)。
‘*’ 匹配任何長度字符序列(包括空序列)。

image 19
可以看一下這些例子(引用 : https://www.youtube.com/watch?v=dz8MOEDomRs)

Python

動態規劃解題:

class Solution:
    def isMatch(self, s, p):
        dp = [[False for _ in range(len(p)+1)] for i in range(len(s)+1)]
        dp[0][0] = True

        #當s為空的時候,可能滿足'*',而且要確定前一個數不是'*',才返回true
        for j in range(1, len(p)+1):
            if p[j-1] != '*':
                break
            dp[0][j] = True
                
        for i in range(1, len(s)+1):
            for j in range(1, len(p)+1):

            #當 p上一個字符爲'?'或者p上一個字符等於s上一個字符,則當前值與          上一位相同
                if p[j-1] == '?' or s[i-1] == p[j-1]:  
                    dp[i][j] = dp[i-1][j-1]

                #p上一個字符爲'*'時,則當前值等於p往後走一位或者s往後走一位
                elif p[j-1] == '*':
                    dp[i][j] = dp[i-1][j] or dp[i][j-1]
        return dp[-1][-1]

DFS求解 : 動態規劃類似

class Solution:
    def isMatch(self, s: str, p: str) -> bool:
        
        def dfs(i, j):
            if j == len(p):  
                return i == len(s)

            if i < len(s) and (s[i] == p[j] or p[j] == '?'):  # Match Single character
                return dfs(i + 1, j + 1)
            
            if p[j] == '*':
                return dfs(i, j + 1) or i < len(s) and dfs(i + 1, j)  # Match zero or one or more character
            
            return False

        return dfs(0, 0)

C++

Bottom up法:

dp[0][0]=true or 1。這是因為如果模式和匹配字符串的長度為0,則它們相等或匹配。

我們可以填充 dp 的第一行。 DP 的第一行告訴我們匹配的字符串長度為零,然後直到模式匹配空字符串的那一列。 所以我們知道只有當那個點的模式字符是’‘時才會發生,如果除了’‘之外還有其他任何東西,那麼我們就會中斷。

現在,我們可以開始填充 dp 的第二行,如果模式在 j-1 處是 ‘ * ‘,那麼我們可以使用它來匹配,在這種情況下它將等於 dp[i-1][j] 和 如果我們對’*’使用空字符串,那麼它等於dp[i][j-1]。

如果 j-1 處的模式不是 ‘ * ‘ 那麼我們需要檢查字符是否相等或 j-1 處的模式字符是否為 ‘ ? ‘ 然後 dp[i][j] =dp[i-1][j-1];

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