[leetcode] Wildcard Matching


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


https://oj.leetcode.com/problems/wildcard-matching/

思路1:二维动归(提交竟然空间超出错误)。 dp[i][j]代表p[0...i]是否匹配 s[0...j]。

  • 如果p[i]!='*',t[i][j] == true 当 t[i-1][j-1]==true &&(p[i]==s[j]||p[i]='.')
  • 如果p[i]=='*',t[i][j]== true 当 其中一个m使得 t[i-1][m]==true,where 0<=m<j.

思路2:二维状态压缩为一维,原理是一样的。


思路1和思路2代码:

/**
 * http://www.darrensunny.me/leetcode-wildcard-matching-2/
 * http://www.wangqifox.cn/wordpress/?p=396
 * 
 * @author Dong Jiang
 * 
 */

public class Solution {

    // MLE, the states can be compressed.
    public boolean isMatchOld(String s, String p) {
        if (s == null)
            return p == null;
        if (p == null)
            return s == null;

        int m = p.length();
        int n = s.length();

        boolean[][] dp = new boolean[m + 1][n + 1];
        dp[0][0] = true;
        for (int i = 1; i <= m; i++) {
            if (p.charAt(i - 1) == '*') {
                int j = n + 1;
                for (int k = 0; k <= n; k++) {
                    if (dp[i - 1][k])
                        j = k;
                }
                for (; j <= n; j++)
                    dp[i][j] = true;

            } else {
                for (int j = 1; j <= n; j++) {
                    if (dp[i - 1][j - 1] && (p.charAt(i - 1) == s.charAt(j - 1) || p.charAt(i - 1) == '?'))
                        dp[i][j] = true;
                }
            }
            dp[i][0] = dp[i - 1][0] && (p.charAt(i - 1) == '*');
        }

        return dp[m][n];
    }

    public boolean isMatch(String s, String p) {
        if (s == null)
            return p == null;
        if (p == null)
            return s == null;

        int m = p.length();
        int n = s.length();

        int count = 0;
        for (int i = 0; i < m; i++) {
            if (p.charAt(i) != '*')
                count++;
        }
        if (count > n)
            return false;

        boolean[] dp = new boolean[n + 1];
        dp[0] = true;
        for (int i = 1; i <= m; i++) {
            if (p.charAt(i - 1) == '*') {
                int j = n+1;
                for (int k = 0; k <= n; k++) {
                    if (dp[k]){
                        j = k;
                        break;
                    }
                }
                for (; j <= n; j++)
                    dp[j] = true;

            } else {
                for (int j = n; j >= 1; j--) {
                    dp[j]= (dp[j - 1] && (p.charAt(i - 1) == s.charAt(j - 1) || p.charAt(i - 1) == '?'));
                }
            }
            dp[0] = dp[0] && (p.charAt(i - 1) == '*');
        }

        return dp[n];
    }

    public static void main(String[] args) {
        System.out.println(new Solution().isMatch("ab", "*a"));
    }
}



参考:

http://www.darrensunny.me/leetcode-wildcard-matching-2/

http://www.wangqifox.cn/wordpress/?p=396



你可能感兴趣的:(java,LeetCode,dp,String)