[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()];
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM