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 lettersa-z
.p
could be empty and contains only lowercase lettersa-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(T−i) and O(P - 2*j)O(P−2∗j) 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+P−i−2j). 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.