DP专项训练:leetcode44.通配符匹配

// 44.通配符匹配  dp专项训练 4.21每日一题
/*
 * 给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。
 * '?' 可以匹配任何单个字符。'*' 可以匹配任意字符串(包括空字符串)。
 * 两个字符串完全匹配才算匹配成功。
 * s 可能为空,且只包含从 a-z 的小写字母。
 * p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *。
 * */

/*
 * -------------------------------------------------------------
 * 思路:
 * dp[i][j]表示 截止到字符串s的第i个位置和字符串p的第j个位置,能否成功匹配
 * dp[0][0]初始化为true,因为空字符串一定和空字符串匹配
 * i和j代表的是真实下标,而不是数组下标。所以写程序的时候注意要-1的地方
 * -------------------------------------------------------------
 * 当p[j]=='?'时,dp[i][j] = dp[i-1][j-1]
 * 当p[j]=='*'时,dp[i][j] = true(if 存在dp[i-X][j-1]==true ,X可以取0,1,2...s.length)
 *         else: dp[i][j] = false
 * OtherWise:
 * if(s[i]==p[j])  dp[i][j] = dp[i-1][j-1]
 * else: dp[i][j] = false
 * -------------------------------------------------------------
 * 返回:  dp[s.length][p.length]
 * */
public class Solution44 {
    public boolean isMatch(String s, String p) {
        // 首先考虑特殊情况,s为空
        if (s.length() == 0) {
            //只要p里存在不为*的字符,就返回false,否则返回true
            for (int i = 0; i < p.length(); i++) {
                if (p.charAt(i) != '*')
                    return false;
            }
            return true;
        }
        // 特殊情况:p为空,只要s不为空,则返回false
        if (s.length() != 0 && p.length() == 0)
            return false;
        int i = 0, j = 0;
        boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
        dp[0][0] = true;
        dp[1][0] = false;
        if (p.charAt(0) == '*') {
            dp[0][1] = true;
            // 特殊情况: p: [***h0]
            // 要首先查看p开头有几个*
            for (int i1 = 1; i1 < p.length(); i1++) {
                if(p.charAt(i1) == '*'){
                    dp[0][i1+1]=true;
                }else {
                    dp[0][i1+1]=false;
                    break;
                }
            }
        } else
            dp[0][1] = false;
        // 初始化完毕,开始dp
        for (i = 1; i < dp.length; i++) {
            for (j = 1; j < dp[0].length; j++) {
                if (p.charAt(j - 1) == '*') {
                    // 寻找是否存在dp[i-X][j-1]==true,如果存在,则dp[i][j] = true
                    int X;
                    for (X = 0; X <= i; X++) {
                        if (dp[i - X][j - 1] == true) {
                            dp[i][j] = true;
                            break;
                        }
                    }
                    if (X > i) {
                        dp[i][j] = false;
                    }
                } else if (p.charAt(j - 1) == '?') {
                    dp[i][j] = dp[i - 1][j - 1];
                } else {
                    // p[j]为其他字符的情况
                    if (s.charAt(i - 1) == p.charAt(j - 1)) {
                        dp[i][j] = dp[i - 1][j - 1];
                    } else {
                        dp[i][j] = false;
                    }
                }
            }
        }
        return dp[s.length()][p.length()];
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值