Wildcard Matching

Wildcard Matching

问题:

'?' Matches any single character.

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

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

思路:

  动态规划

我的代码:

public class Solution {
    /**
     * @param s: A string 
     * @param p: A string includes "?" and "*"
     * @return: A boolean
     */
    public boolean isMatch(String s, String p) {
        // write your code here
        if((s==null || s.length()==0) && (p==null || p.length()==0))    return true;
            if(s==null || s.length()==0)    return false;
            if(p==null || p.length()==0)    return false;
            int row = p.length();
            int col = s.length();
            boolean[][] isValid = new boolean[row][col];
            if(p.charAt(0) == '*')
            {
                for(int j=0; j<col; j++)
                {
                    isValid[0][j] = true;
                } 
            }
            if(p.charAt(0)==s.charAt(0) || p.charAt(0)=='?')    isValid[0][0] = true;
            boolean first = true;
            for(int i=0; i<row; i++)
            {
                if(p.charAt(i)==s.charAt(0) || p.charAt(i)=='?')
                {
                    if(first)
                    {
                        isValid[i][0] = i==0?true:isValid[i-1][0];
                        first = false;
                    }
                }
                else if(p.charAt(i) == '*') 
                {
                    if(i==0) isValid[i][0] = true;
                    else isValid[i][0] = isValid[i-1][0];
                }
            }
            for(int i=1; i<row; i++)
            {
                for(int j=1; j<col; j++)
                {
                    if(p.charAt(i)=='*')
                    {
                        if(isValid[i-1][j] || isValid[i][j-1])  isValid[i][j] = true;
                    }
                    if(p.charAt(i)==s.charAt(j) || p.charAt(i)=='?')
                    {
                        if(isValid[i-1][j-1]) isValid[i][j] = true;
                    }
                }
            }
            return isValid[row-1][col-1];
     }
}
View Code

我的代码2:

public class Solution {
    public boolean isMatch(String s, String p) {
            if((s==null || s.length()==0) && (p==null || p.length()==0))    return true;
            int n = s.length();
            int m = p.length();
            int count = 0;
            for (int i = 0; i < m; i++) {
                if (p.charAt(i) == '*') count++;
            }
            if (count==0 && m != n) return false;
            else if (m - count > n) return false;
            
            boolean[] isValid = new boolean[n+1];
            isValid[0] = true;
            for(int i=0; i<m; i++)
            {
                if(p.charAt(i) == '*')
                {
                    for(int j=0; j<n; j++)
                        isValid[j+1] |= isValid[j];
                }
                else
                {
                    for(int j=n-1; j>=0; j--)
                    {
                        isValid[j+1] = ((p.charAt(i)=='?' || p.charAt(i)==s.charAt(j)) && isValid[j]);
                    }
                    isValid[0] = false;
                }
            }
            return isValid[n];
    }
}
View Code

学习之处:

  • 通过逆向思维相处动态规划的方程是什么
  • 第一次代码的时候,通过用二维的数组row 代表 p col代表 s 通过isValid[i][j] = isValid[i-1][j-1] && (p.charAt(i)==s.charAt(j) || p.charAt(i)=='?') isValid[i][j] = (isValid[i-1][j]|isValid[i][j-1]) 而这种方式下,可以通过lintcode,通过不了Leetcode, 显示二维数组内存过大了。。
  • 第二次代码,转换成一维数组,思想和maxmum jump 每一次p.charAt(j)去找到可以判断的最远距离,下一次j+1,更新最远距离,思路已经想明白了,写代码的时候就混乱好多,看了一下别人的代码,思路架构都一致,可惜对方可以通过,自己未过,有点遗憾,根据别人的代码,修改了一下自己的代码,便通过了。关键点在于对于‘*’从前往后,对于'?'|'a-z'从后往前