LEETCODE專題
10. Regular Expression Matching
首先我們先來看一下題目要求:
這裏先要講講題目的要求。
這裏題目要求需要來個分類討論,一個大類是p中’‘字符, 另一個大類是p中的非’‘字符。這裏需要進行一個條件判斷。這也是這道題的一個大坑。
如果單單從條件判斷來進行,就要考慮很多種情況,測試的輸入比樣例的輸入要複雜得多,多樣得多。譬如s=”aaa”, p=”a*ab*c*”; s=”aacccbbaabb”, p=”.aabb”。這樣就要考慮非’‘字符優先匹配。剛開始筆者陷入這個坑中的時候甚至還想過開兩個隊列來存儲非’‘字符和’‘,以便分開匹配。但是這一條路走到黑,也的確就是黑了。
後來學了動態規劃之後發現其實這個問題是有最優子結構的,也就是說兩個字符串的前綴就是這個問題的子問題。
參照揹包問題的動態規劃解法,我們可以新建一個二維數組,如m[x][y]來記錄兩個字串的匹配與否。例如,m[0][0]表示取s的0個字符,p的0個字符來進行匹配,匹配結果爲true;m[2][3]表示取s的2個字符,p的3個字符進行匹配。
接下來就是分類的處理:
- 不帶’*’的字符匹配:直接匹配當前的s字符和p字符
帶’*’的字符匹配:若s當前字符與p的上一個字符不匹配,則兩個字符串仍然能夠匹配的可能就是p的帶’*’字符和p的上一個字符的組成字符串匹配數爲0;如果s當前字符與p的上一個字符匹配,則兩個字符串能夠匹配的可能就是s的上一個字符和p的帶’*’字符及上一個字符的組成字符串匹配,或者我們可以選擇不匹配。
這裏注意下,能夠匹配並不僅僅意味着兩個字符一模一樣,也有可能p的當前字符爲’.’,能夠匹配任何字符。
下面直接上代碼:
class Solution {
public:
bool isMatch(string s, string p) {
/**
* This problem is a typical knapsack
* of prefix, we can then set the 2-D
* bool matrix for matched.
* m[i][j] stands for
* s[0, 1..i - 1]
* is matched with
* p[0, 1..j - 1]
*
* Also, there are 2 situations we can
* tell if they are matched;
* 1. p[j - 1] != '*', then
* (m[i - 1][j - 1] &&
* (s[i - 1] == p[j - 1] ||
* p[j - 1] == '.') ) must be TRUE
* OR
* 2. p[j - 1] == '*', then
* a.if p[j - 2] cannot be matched,
* m[i][j - 2] must be TRUE
* OR
* b.if p[j - 2] can be matched
* (p[j - 2] can be '.'), then
* (s[i - 1] == p[j - 2] ||
* p[j - 2] == '.') &&
* m[i - 1][j] must be TRUE
**/
// firstly, check if both of them are empty
if (s.empty() && p.empty()) return true;
else if (p.empty()) return false;
int iend = s.size() + 1;
int jend = p.size() + 1;
int i, j;
vector<vector<bool> > m(iend, vector<bool>(jend, false));
m[0][0] = true;
for (j = 1; j < jend; j++) {
m[0][j] = (j > 1 && p[j - 1] == '*' && m[0][j - 2]);
}
for (i = 1; i < iend; i++) {
m[i][0] = false;
}
// matching begins
for (i = 1; i < iend; i++) {
for (j = 1; j < jend; j++) {
if (p[j - 1] != '*') {
m[i][j] = m[i - 1][j - 1] &&
(s[i - 1] == p[j - 1] || p[j - 1] == '.');
} else if (j > 1) {
if (p[j - 2] != s[i - 1] && p[j - 2] != '.') {
m[i][j] = m[i][j - 2];
} else {
m[i][j] = (m[i - 1][j] || m[i][j - 2]);
}
} else {
m[i][j] = false;
}
}
}
return m[iend - 1][jend - 1];
}
};
時間複雜度:O(n^2)