1. 程式人生 > >LeetCode - 10 - Regular Expression Matching

LeetCode - 10 - Regular Expression Matching

http 當前 matching ·· tps 復雜度 ble blog ima

題目

URL:https://leetcode.com/problems/regular-expression-matching

技術分享

解法

動態規劃。

  1. p[i - 1] == s[i - 1], dp[i][j] = dp[i - 1][j - 1]:字符匹配,如 ‘a‘ 匹配 ‘a‘,兩個字符匹配的情況下,看兩個字符之前字符的匹配情況。
  2. p[i - 1] = ‘.‘, dp[i][j] = dp[i - 1][j - 1]: ‘.‘ 匹配,如 ‘.‘ 匹配 ‘a‘,兩個字符匹配的情況下,要看兩個字符之前字符的匹配情況。
  3. p[i - 1] = ‘*‘: ‘*‘匹配,具體如下。

‘*‘ 匹配包括三種情況:

  1. dp[i][j] = dp[i][j - 2]:‘*‘ 配空字符,如 "" 匹配 "a*"。對於 p,需要回退有關 ‘*‘ 和與 ‘*‘ 組合的字符,再看字符的匹配情況。
  2. p[i - 1] == s[i - 1] || s[i - 1] = ‘.‘, dp[i][j] = dp[i - 1][j - 2] || 上一個情況:‘*‘ 匹配一個字符,如 "a" 匹配 "a*"。對於 s 和 p,s 需要回退當前字符,需要回退有關 ‘*‘ 和與 ‘*‘ 組合的字符。假設匹配字符失敗,那麽 ‘*‘ 可能是匹配空字符,需要判斷空字符的情況。
  3. p[i - 1] == s[i - 1] || s[i - 1] = ‘.‘, dp[i][j] = dp[i - 1][j] || 上兩個情況:‘*‘ 匹配多個字符,如 "aaa" 匹配 "a*",對於 s 來說,s 需要回退當前字符,p 需要留下當前字符與之前的情況進行匹配。

初始狀態也需要考慮:

  • dp[0][0] 肯定為 true。
  • dp[0][i], i ∈ {2, 4, 6, ······, p.length},意思是 s 為空字符串,當 p 為 "a*b*" 類似的模式時,dp[0][i] 為 true,否則 false。
  • dp[i][0], i ∈ {1, 2, 3, ······, s.length},意思是 p 為空字符串,肯定不匹配,為 false。
    public boolean isMatch(String s, String p) {
        boolean[][] dp = new boolean[s.length() + 1][p.length() + 1];
        dp[
0][0] = true; for (int i = 2; i <= p.length(); i += 2) { if (p.charAt(i - 1) == ‘*‘) dp[0][i] = true; else break; } for (int i = 1; i <= s.length(); i++) { for (int j = 1; j <= p.length(); j++) { if (s.charAt(i - 1) == p.charAt(j - 1) || p.charAt(j - 1) == ‘.‘) { // . or other character satified s[i] = p[j] dp[i][j] = dp[i - 1][j - 1]; } else if (j >= 2 && p.charAt(j - 1) == ‘*‘) { // *, size = 1, size > 1 if (p.charAt(j - 2) == ‘.‘ || s.charAt(i - 1) == p.charAt(j - 2)) { dp[i][j] = dp[i - 1][j - 2] || dp[i - 1][j]; } // *, size = 0 dp[i][j] = dp[i][j] || dp[i][j - 2]; } } } return dp[s.length()][p.length()]; }

動態規劃,時間復雜度O(s.length * p.length),運行時間約為 32 ms

總結

這個題目真的是難,動態規劃的題目沒有幾個是簡單的。曾經因為這個題目我放棄了刷 Leetcode,最近幾天苦心研究,終於得出答案了。這可能是我最近最開心的一件事了。

動態規劃最重要的一點是狀態轉移,只要能列出初始狀態,寫出狀態轉移方程,之後的問題就很好解決。

LeetCode - 10 - Regular Expression Matching