LeetCode 10: Regular Expression Matching

Description:正則表達式

Given an input string (s) and a pattern (p), implement regular expression matching with support for '.' and '*'.express

'.' Matches any single character.
'*' Matches zero or more of the preceding element.

The matching should cover the entire input string (not partial).ide

Note:函數

  • s could be empty and contains only lowercase letters a-z.
  • p could be empty and contains only lowercase letters a-z, and characters like . or *.

Example 1:ui

Input:
s = "aa"
p = "a"
Output: false
Explanation: "a" does not match the entire string "aa".

Example 2:this

Input:
s = "aa"
p = "a*"
Output: true
Explanation: '*' means zero or more of the precedeng element, 'a'. Therefore, by repeating 'a' once, it becomes "aa".

Example 3:spa

Input:
s = "ab"
p = ".*"
Output: true
Explanation: ".*" means "zero or more (*) of any character (.)".

Example 4:code

Input:
s = "aab"
p = "c*a*b"
Output: true
Explanation: c can be repeated 0 times, a can be repeated 1 time. Therefore it matches "aab".

Example 5:blog

Input:
s = "mississippi"
p = "mis*is*p*."
Output: false

描述:遞歸

給定字符串(s)和模式(p),實現支持'*’和‘.’的正則表達式匹配。

‘.’:匹配任意字符
‘*’:匹配零個或多個前綴字符

要求:模式匹配覆蓋整個輸入字符,而不是部分字符。

輸入字符串s爲空,或者只包含小寫字母a-z;

模式p能夠爲空,或者只包含小寫字母a-z和特殊字符'*'、‘.’。

例子1:

輸入:
s = "aa"
p = "a"
輸出: false
說明: "a"不能匹配整個輸入字符串"aa".

例子2:

輸入:
s = "aa"
p = "a*"
輸出: true
說明: '*'表明0個或多個前綴字符'a'. 所以, 重複一次'a' , 變爲"aa".

例子3:

輸入:
s = "ab"
p = ".*"
輸出: true
Explanation: ".*" 表示0個或多個 (*) 任意字符 (.)。

例子4:

輸入:
s = "aab"
p = "c*a*b"
輸出: true
說明: c能夠出現0次, a能夠出現兩次. 所以匹配輸入字符"aab"。

例子5:

輸入:
s = "mississippi"
p = "mis*is*p*."
輸出: false

 

方法一:迭代法

首先,咱們考慮不包含字符‘*’的情形,‘.’能夠和任意字符匹配。咱們首先判斷第一個字符是否相等,若是相等則遞歸判斷剩下的字符是否相等。

代碼以下:

class Solution {
public:
    bool isMatch(string s, string p) {
        if(p.length() == 0) return s.length() == 0;
        bool first_match = (s.length() != 0 && (s[0] == p[0] || p[0] == '.'));
        return first_match && isMatch(s.substr(1), p.substr(1));
    }
};

 接着,咱們考慮存在‘*’的情形。這裏存在兩種狀況:

1. 輸入字符的首字符和模式的首字符不匹配,如s=「abc」,p=「c*abc」,此時跳過模式p的前兩個字符,進行後續比較,即輸入s=「abc」,p="abc"。

2. 輸入字符的首字符和模式的首字符匹配,如s=「abc」,p=「a*bc」,因爲‘*’能夠表示多個前綴字符,此時跳過輸入字符的首字符,進行後續比較,即輸入s=「bc」,p="a*bc"。

 

class Solution {
public:
    bool isMatch(string s, string p) {
        if(p.length() == 0) return s.length() == 0;
        bool first_match = (s.length() != 0 && (s[0] == p[0] || p[0] == '.'));
        if(p.length() >= 2 && p[1] == '*') {
            return isMatch(s, p.substr(2)) || (first_match && isMatch(s.substr(1), p));
        } else {
            return first_match && isMatch(s.substr(1), p.substr(1));
        }
    }
};

  

複雜度分析:

  • 時間複雜度: 以T和P分別表示輸入字符串s和模式字符串p的長度。最壞情形下,對函數match(text[i:], pattern[2j:]) 的調用次數爲:will be made \binom{i+j}{i}(ii+j​​) times, and strings of the order O(T - i)O(Ti) and O(P - 2*j)O(P2j) will be made. Thus, the complexity has the order \sum_{i = 0}^T \sum_{j = 0}^{P/2} \binom{i+j}{i} O(T+P-i-2j)i=0T​​j=0P/2​​(ii+j​​)O(T+Pi2j). With some effort outside the scope of this article, we can show this is bounded by O\big((T+P)2^{T + \frac{P}{2}}\big)O((T+P)2T+2P​​​​).
  • Space Complexity: For every call to match, we will create those strings as described above, possibly creating duplicates. If memory is not freed, this will also take a total of O\big((T+P)2^{T + \frac{P}{2}}\big)O((T+P)2T+2P​​​​) space, even though there are only order O(T^2 + P^2)O(T2​​+P2​​) unique suffixes of PP and TT that are actually required. 

相關文章
相關標籤/搜索