44. Wildcard Matching

Description

Implement wildcard pattern matching with support for '?' and '*'.

'?' Matches any single character.
'*' Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:
bool isMatch(const char *s, const char *p)

Some examples:

isMatch("aa","a") → false
isMatch("aa","aa") → true
isMatch("aaa","aa") → false
isMatch("aa", "") → true
isMatch("aa", "a
") → true
isMatch("ab", "?") → true
isMatch("aab", "c
a*b") → false

Solution

2D-DP, O(mn), S(mn)

亏我以前还用很神奇的recursion做,还过了...如今看来直接上DP大法啊。

思路跟"Regular Expression Matching"一样,细节更简单些。

class Solution {
    public boolean isMatch(String s, String p) {
        if (s == null || p == null) {
            return false;
        }
        
        int m = s.length();
        int n = p.length();
        boolean[][] dp = new boolean[m + 1][n + 1];
        
        dp[0][0] = true;
        for (int j = 1; j <= n; ++j) {  // initialize dp[0][j] specially
            if (p.charAt(j - 1) != '*') break;
            dp[0][j] = true;
        }
        
        for (int i = 1; i <= m; ++i) {
            for (int j = 1; j <= n; ++j) {
                if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?') {
                    dp[i][j] = dp[i - 1][j - 1];
                } else if (p.charAt(j - 1) == '*') {
                    dp[i][j] = dp[i][j - 1] || dp[i - 1][j]; // match empty or multiple
                }
            }
        }
        
        return dp[m][n];
    }
}

1D-DP, O(mn), S(n)

好容易出bug...注意不仅需要处理初始化,在遍历s的时候,我们会发现dp[0]的值不会被更新,所以要直接set dp[0]的值!
dp[0]代表s.substring(0, i + 1) match p.substring(0, 0), 也就是s.substring(0, i + 1)是否为空!所以直接将dp[0]置成false。

class Solution {
    public boolean isMatch(String s, String p) {
        if (s == null || p == null) {
            return false;
        }
        
        int n = p.length();
        boolean[] dp = new boolean[n + 1];
        dp[0] = true;
        for (int j = 1; j < dp.length && dp[j - 1]; ++j) {  // initialize!
            if (p.charAt(j - 1) == '*') {
                dp[j] = true;
            }
        }
        
        for (int i = 0; i < s.length(); ++i) {
            boolean prev = dp[0];
            dp[0] = false;  // tricky!!!

            for (int j = 0; j < n; ++j) {
                boolean tmp = dp[j + 1];
                
                if (s.charAt(i) == p.charAt(j) || p.charAt(j) == '?') {
                    dp[j + 1] = prev;
                } else if (p.charAt(j) == '*') {
                    dp[j + 1] = dp[j] || dp[j + 1];
                } else {
                    dp[j + 1] = false;
                }
                
                prev = tmp;
            }
        }
        
        return dp[n];
    }
}

你可能感兴趣的:(44. Wildcard Matching)