Leetcode--Wildcard Matching

Topic: Hard Mode


Question:

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
» Solve this problem


Method:

OK, hardest question I ever met, and today is July-22-2013.

Basic idea is traverse the p-string from left to right and s-string from right to left. 

Create a boolean DP array, and set the first one be true.

If p-index point to a '*', set true from firstmatch to s-length for dp.

Or, traverse s-string from right to firstmatch position, and once the character in s-string has the following conditions: 1. equals to current pointed p-string character; 2. p-string's current pointing character is '?'; 3. the previous dp position is true, then we can set the current dp to true. After that, we keep the record of the minimum true position in dp and give it to a variable which originally is -1.

Then, after this traverse, if the value of variable is still -1, we return false. Or, we put the variable value into firstmatch variable, and go to the next round of traversing p-string.

Much more details should be read from the code.


Code:

public class Solution {
    public boolean isMatch(String s, String p) {
        // Start typing your Java solution below
        // DO NOT write main() function
        int pid = 0, firstmatch = 0;
        boolean[] dp = new boolean[s.length()+1];
        
        int count = 0;
        for (Character c : p.toCharArray()) {
            if (c != '*')  ++count;
        }
        if (count > s.length())  return false;
        
        dp[0] = true;
        while(pid < p.length()){
            if(pid>0 && p.charAt(pid)=='*' && p.charAt(pid-1)=='*'){
                pid++;
                continue;
            }
            
            if(p.charAt(pid) == '*')
                for(int i=firstmatch; i<=s.length(); i++)
                    dp[i] = true;
            else{
                int match = -1;
                for(int i=s.length(); i>firstmatch; i--){
                    dp[i] = dp[i-1] && (p.charAt(pid) == '?' || p.charAt(pid) == s.charAt(i-1));
                    if(dp[i]) match = i;
                }
                if(match < 0) return false;
                firstmatch = match;
            }
            pid++;
        }
        
        return dp[s.length()];
    }
}

Summary:

Very hard. Spent two days on it. Though I know how it works, still can't figure it out.


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值