zoukankan      html  css  js  c++  java
  • [leetcode] 44. 通配符匹配(Java)(动态规划)

    44. 通配符匹配

    动态规划

    做动态规划很简单,三步走:

    第一步,判断可否用动态规划做,即判断是否满足两个条件:①最优子结构,②重叠子问题。显然该题求s与p是否match,可由其字串层层分解上来。
    我语文不好一两句解释不清楚,不过看完这篇文章,基本就会判断是不是满足这两个条件了。
    算法-动态规划 Dynamic Programming--从菜鸟到老鸟

    第二步,描述状态。这个题的状态还是比较好描述的,boolean f[i][j] :表示子串s[0~i-1] 与子串p[0~j-1]是否match

    第三步,找出状态转移方程以及初始状态:

    最难的地方就在于如何找状态转移方程。
    如何找?即分析当前状态由上层哪个或者哪些以及处理过的状态转换而来
    假设题中没有*,那就简单了,状态转移方程为f[i][j] = f[i-1][j-1] && s[i]==p[j]

    现在加上,我们就可以按情况讨论嘛,如果p[j]!='' ,那么状态转移方程就是f[i][j] = f[i-1][j-1] && s[i]p[j]
    如果p[j]
    '' , 即可以代替0个、1个或者多个,对于的状态f[i][j]可以由f[i-1][j-1],f[i][j-1]和f[i-1][j]而来,即f[i][j] = f[i - 1][j - 1] || f[i - 1][j] || f[i][j - 1];

    初始状态,显然f[0][0]=true
    不过,还有一个初始状态很容易被遗忘:
    当p以开头时
    if (p.length() > 0 && p.charAt(0) == '
    ') {
    f[0][1] = true;
    }

    代码

    class Solution {
        public boolean isMatch(String s, String p) {
            String tp = "";
    
            //处理p中多余的*
            for (int i = 0; i < p.length(); i++) {
                if (p.charAt(i) == '*') {
                    tp += '*';
                    while (i < p.length() && p.charAt(i) == '*') i++;
                }
                if (i < p.length()) {
                    tp += p.charAt(i);
                }
            }
            p = tp;
    
            boolean[][] f = new boolean[s.length() + 1][p.length() + 1];
            f[0][0] = true;
    
            // 注意,当p以*开头时
            if (p.length() > 0 && p.charAt(0) == '*') {
                f[0][1] = true;
            }
    
            for (int i = 1; i <= s.length(); i++) {
                for (int j = 1; j <= p.length(); j++) {
                    if (p.charAt(j - 1) == '*') {
                        f[i][j] = f[i - 1][j - 1] || f[i - 1][j] || f[i][j - 1];
                    } else {
                        f[i][j] = f[i - 1][j - 1] && (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == '?');
                    }
                }
            }
    
            return f[s.length()][p.length()];
        }
    }
    
  • 相关阅读:
    纯CSS打造可折叠树状菜单
    c++ Constructor FAQ 继续
    Java设计模式偷跑系列(六)Singleton模式的建模与实现
    优秀的产品经理是怎样炼成的?
    Pki原则
    屌丝男初中丰富的工作实践反击
    Android Material Design带UI变化
    unity多边形uv地图
    BZOJ 1208 HNOI2004 宠物收容所 平衡树/set
    [连载]Java程序设计(04)---任务驱动的方法:工资结算系统
  • 原文地址:https://www.cnblogs.com/acbingo/p/9346378.html
Copyright © 2011-2022 走看看