LeetCode - 解題筆記 - 10- Regular Expression Matching
Regular Expression Matching
Solution 1
【官方題解】看到體面想到了非常複雜的星號匹配規則直接懵逼了……以為是狀態機,所以想到了DP,但是沒有對問題建模清楚。官方的題解很有分析意義,因此這裡直接使用這個題解。定義最優子結構ans[i][j]
表示輸入的第i+1
個字元及以後與正則的第j+1
個字元及以後的匹配結果。更新狀態按照正則匹配規則更新即可。邊界條件上有三個地方:如果正則為空,輸入只有為空時才匹配正確;二者的末尾空值匹配結果為dp[S][P] = true
,作為初始值用於迭代;輸入末尾空值dp[S][P-1]
不能直接置true
,因為如果正則末尾恰為星號需要額外進行判斷,需要在迭代時考慮正則與輸入末尾空值的比較。
這麼一看這個並不是很複雜,aaaa
和a*a*
的匹配我想複雜了,動態規劃可以將5種匹配方案都涵蓋進去。
- 時間複雜度: O ( S P ) O(SP) O(SP), S S S和 P P P分別是輸入和正則的長度
- 空間複雜度: O ( S P ) O(SP) O(SP), S S S和 P P P分別是輸入和正則的長度
class Solution {
public:
bool isMatch(string s, string p) {
// 邊界判定:空空為true
if (p.size() == 0) {
return s.size() == 0;
}
vector<vector<bool>> ans(s.size() + 1, vector<bool>(p.size() + 1, false));
ans[s.size()][p.size()] = true;
for (int i = s.size(); i >= 0; i--) {
// 這裡考察末尾空的情況主要是應對正則最後一個是*的情形
for (int j = p.size() - 1; j >= 0; j--) {
// 當前位置匹配:字母相同或者字母萬用字元
// 如果正則末尾是*,直接和輸入末尾空比較為負,否則會進入二者的末尾空比較,true
bool current = (i < s.size()) && (s.at(i) == p.at(j) || p.at(j) == '.');
// 星號判斷
if (j + 1 < p.size() && p.at(j + 1) == '*') {
// 0次,直接跳過p中的這兩個字元;任意多次,當前匹配正確並向後檢視s
ans[i][j] = (ans[i][j + 2] || current && ans[i + 1][j]);
} else {
ans[i][j] = current && ans[i + 1][j + 1];
}
// cout << i << j << ans[i][j] << endl;
}
}
return ans[0][0];
}
};
Solution 2
Solution 1的Python實現
class Solution:
def isMatch(self, s: str, p: str) -> bool:
if len(p) == 0:
return (len(s) == 0)
ans = [[False] * (len(p) + 1) for _ in range(len(s) + 1)]
# print(ans)
ans[len(s)][len(p)] = True
# print(len(s), len(p), ans)
for i in range(len(s), -1, -1):
for j in range(len(p) - 1, -1, -1):
current = (i < len(s)) and ((s[i] == p[j]) or (p[j] == '.'))
if j + 1 < len(p) and p[j + 1] == '*':
ans[i][j] = (ans[i][j + 2]) or (current and ans[i + 1][j])
else:
ans[i][j] = current and ans[i + 1][j + 1]
# print(i, j, ans[i][j], ans)
return ans[0][0]
相關文章
- Leetcode 10 Regular Expression MatchingLeetCodeExpress
- [LeetCode Python3]10. Regular Expression Matching手把手詳解——正規表示式(一)LeetCodePythonExpress
- Hyperscan is generally vulnerable to regular expression denial of service (ReDoS)Express
- LeetCode - 解題筆記 - 12 - Integer to RomanLeetCode筆記
- LeetCode - 解題筆記 - 8 - Palindrome NumberLeetCode筆記
- LeetCode - 解題筆記 - 7 - Reverse IntegerLeetCode筆記
- perl next, last, regular expression 實用場景ASTExpress
- leetcode刷題筆記LeetCode筆記
- LeetCode 刷題筆記LeetCode筆記
- leetcode刷題筆記605LeetCode筆記
- [leetcode] 1023. Camelcase MatchingLeetCode
- leetcode刷題筆記(3)(python)LeetCode筆記Python
- Learning Semantic Concepts and Order for Image and Sentence Matching筆記筆記
- [LeetCode] 282. Expression Add OperatorsLeetCodeExpress
- leetcode刷題筆記8.5-8.9LeetCode筆記
- Leetcode刷題筆記8.12-8.16LeetCode筆記
- LeetCode刷題筆記9.2-9.9LeetCode筆記
- CF1948G MST with Matching 題解
- [ABC126F] XOR Matching 題解
- 題解筆記筆記
- Pytest學習筆記10-生成html報告筆記HTML
- MoveIt! 學習筆記10- Planning with Approximated Constraint Manifolds筆記APPAI
- SpringMVC學習筆記10-異常處理SpringMVC筆記
- atcoder regular 175 題解 A-C D還未解決
- Leetcode171-190刷題筆記(非困難題)LeetCode筆記
- Leetcode 記錄 不會解的題LeetCode
- LeetCode解題記錄(雙指標專題)LeetCode指標
- LeetCode刷題記錄與題解(C++版本)LeetCodeC++
- leetCode解題記錄1 - 兩數之和LeetCode
- 刷題記錄:劍指offer+遇到的筆試題+LeetCode筆試LeetCode
- 【刷題筆記】LeetCode-53 最大子陣列和筆記LeetCode陣列
- Javascript 設計模式系統講解與應用——學習筆記10-狀態模式JavaScript設計模式筆記
- 模板問題:Knapsack (LeetCode: Coin Change)[揹包問題九講筆記]LeetCode筆記
- Leetcode學習筆記(1)LeetCode筆記
- [leetcode 題解] 849LeetCode
- Leetcode 全套題解LeetCode
- 【LeetCode刷題筆記-33 649:Dota2 參議院】LeetCode筆記
- LeetCode解題記錄(貪心演算法)(二)LeetCode演算法