1. 程式人生 > >LeeCode 10: 給定一個字串 (s) 和一個字元模式 (p)。實現支援 '.' 和 '*' 的正則表示式匹配

LeeCode 10: 給定一個字串 (s) 和一個字元模式 (p)。實現支援 '.' 和 '*' 的正則表示式匹配

題目

給定一個字串 (s) 和一個字元模式 (p)。實現支援 '.' 和 '*' 的正則表示式匹配。

'.' 匹配任意單個字元。
'*' 匹配零個或多個前面的元素。

匹配應該覆蓋整個字串 (s) ,而不是部分字串。

說明:

  • s 可能為空,且只包含從 a-z 的小寫字母。
  • p 可能為空,且只包含從 a-z 的小寫字母,以及字元 . 和 *

示例 1:

輸入:
s = "aa"
p = "a"
輸出: false
解釋: "a" 無法匹配 "aa" 整個字串。

示例 2:

輸入:
s = "aa"
p = "a*"
輸出: true
解釋: '*' 代表可匹配零個或多個前面的元素, 即可以匹配 'a' 。因此, 重複 'a' 一次, 字串可變為 "aa"。

程式碼

class Solution {
    public boolean isMatch(String s, String p) {
        if (s== null || p== null) return false;
        return match(s, 0, p, 0);
    }
    
     private static boolean match(String s, int si, String p, int pi) {
        boolean strDone = si >= s.length();
        boolean regDone = pi >= p.length();
        if (regDone) { // 規則已完成, 字串也結束則匹配成功, 否則失敗
            return strDone;
        }
        if (pi + 1 < p.length() && p.charAt(pi + 1) == '*') {
            if (strDone) {
                return match(s, si, p, pi + 2);
            }
            if (s.charAt(si) == p.charAt(pi) || p.charAt(pi) == '.') {
                // 判斷下個字元跟當前規則是否匹配 或者 當前字元跟下個規則是否匹配
                return match(s, si + 1, p, pi) || match(s, si, p, pi + 2);
            } else { // 字元不相等, 並且也不是., 可能是出現了0次, 直接跳過當前規則
                return match(s, si, p, pi + 2);
            }
        }
        if (si + 1 <= s.length() && (s.charAt(si) == p.charAt(pi) || p.charAt(pi) == '.')) {
            return match(s, si + 1, p, pi + 1);
        }
        return false;
    }
}