LeetCode算法系列:44. Wildcard Matching

题目描述:

Given an input string (s) and a pattern (p), 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).

Note:

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like ? or *.

Example 1:

Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".

Example 2:

Input:
s = "aa"
p = "*"
Output: true
Explanation: '*' matches any sequence.

Example 3:

Input:
s = "cb"
p = "?a"
Output: false
Explanation: '?' matches 'c', but the second letter is 'a', which does not match 'b'.

Example 4:

Input:
s = "adceb"
p = "*a*b"
Output: true
Explanation: The first '*' matches the empty sequence, while the second '*' matches the substring "dce".

Example 5:

Input:
s = "acdcb"
p = "a*c?b"
Output: false
 

算法描述:

递归回溯法---超时

虽然经过多方面的优化,将前后匹配的元素去掉,将中间‘*’重复的去掉等

class Solution {
public:
    bool isMatch(string s, string p) {
        int slen = s.length(),plen = p.length();
        int i = 0;
        while(i < slen && i < plen && p[i] != '*' ){
            if(p[i] != '?' && p[i] != s[i])return false;
            i ++;
        }
        int j = 0;
        while(j < slen - i && j < plen -i && p[plen - j - 1] != '*' ){
            if(p[plen - j - 1] != '?' && p[plen - j - 1] != s[slen - j - 1])
            {
                return false;
            }
            j ++;
        }
        s = s.substr(i, slen - j);
        p = p.substr(i, plen - j);
        // cout << s << endl;
        // cout << p << endl;
        for(int i = p.length() - 2; i >= 0; i --){
            if(p[i] == '*' && p[i + 1] == '*')p.erase(i,1);
        }
        // cout << s << endl;
        // cout << p << endl;
        return isMatch(s, s.length() - 1, p, p.length() - 1);
    }
    bool isMatch(string s, int i, string p, int j){
        if(j == -1){
            if(i == -1)return true;
            else return false;
        }
        if(i >= 0 && (s[i] == p[j] || p[j] == '?'))
            return isMatch(s, i - 1, p, j - 1);
        if(p[j] == '*')
        {
            while(i >= -1){
                if(p[j - 1] == '?' || s[i] == p[j - 1]){
                    if(isMatch(s, i , p, j - 1))
                        return true;
                }
                    
                i --;
            }
            return false;
        }
        return false;
    }
};

采用动态规划的方法,与前面第10题相似

不同的是其中优化了一点,当p中为‘*’与s中某个位置i的元素匹配后,那么p中到‘*’这个位置,可以与s中i及i以后所有的位置匹配

class Solution {
public:
    bool isMatch(string s, string p) {
        int m = s.length();
        int n = p.length();
        bool b[m + 1][n + 1];
        b[0][0] = true;
        for(int i = 1; i <= m ; i ++)b[i][0] = false;
        for(int j = 1; j <= n ; j ++)b[0][j] = p[j - 1] == '*' && b[0][j - 1];
        for(int j = 1; j <= n; j ++)
            for(int i = 1; i <= m; i ++)
            {
                if(p[j - 1] == '*')
                {
                    b[i][j] = false;
                    for(int k = i; k >= 0; k --)
                        if(b[k][j - 1]){
                            b[i][j] = true;
                            break;
                        }
                    if(b[i][j]){
                        for(int t = i; t <= m; t ++ )b[t][j] = true;
                    }
                }
                else{
                    if(p[j - 1] == '?' || p[j - 1] == s[i - 1])b[i][j] = b[i - 1][j - 1];
                    else b[i][j] = false;
                }        
        return b[m][n];
    }
};

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值