leetcode 第10題 Regular Expression Matching
阿新 • • 發佈:2019-02-01
週末也沒有做leetcode,感覺有點罪惡啊,這個第10題好難啊,涉及到遞迴了,看的我是頭暈眼花啊。我看著看著還是有點收穫的,我發現題目仍然沒有我想象中的那麼的簡單,如果s = 'a b c d e',p = '. * e',這樣匹配出的結果也是正確的,我就很納悶兒啊,' . '是匹配任意一個字元,可是我以為只能匹配一個字元,但是從這個算例上看,當它和' * '在一起時,' . '可以多次匹配不同的字元,這個是我不太明白的地方。。好的吧,這樣也讓我更加的明白了題意。這個題真的是很難啊!!
有篇博文寫的這個題目的分析挺不錯的,可以讓人看得懂,連結是:leetcode 10 題目分析 。因為這個分析使用Java寫的程式碼,我把它改成了C++版本並在leetcode上通過了測試。回到題目分析中,裡面的表格就是分析的思路和過程,這個表格非常的重要,為了邏輯清楚,先對p做條件判斷,在此基礎上,再對s做條件判斷。
說明:
對於第4個條件:當p的第二個字元不是星號時,如果S不空且(p.charAt(0)
== s.charAt(0) 或者 p.charAt(0)==‘ . ’),則進入下一層遞迴繼續比較分別擷取首元素的s和p;否則,返回false。
對於第5個條件:當p的第二個字元是星號時,如果S不空且(p.charAt(0)
== s.charAt(0) 或者 p.charAt(0)==‘ . ’),有兩種分支需要分別判斷:
1、某字元+星號不要匹配s的首字元:(因為星號之前的字元可出現可不出現,該情況不配是考慮到後面有必須匹配的。假設當前匹配並截去s的首字元,會導致後續匹配錯誤。) 截去p的前兩個元素(某字元+星號)並進入下一層遞迴,假如返回true,則當前遞迴返回true;假如返回false,進入分支2。
2、某字元+星號要匹配s的首字元:截去s首字元並繼續條件5的判斷。
對於第6個條件:當p的第二個字元是星號時,非【S不空且(p.charAt(0) == s.charAt(0) 或者 p.charAt(0)==‘ . ’)】,截去p的前兩個元素(某字元+星號)並進入下一層遞迴。
下面是我修改的C++版本的程式碼:
class Solution {
public:
bool isMatch(string s, string p) {
if (p.size() == 0) { //對應步驟1
if(s.size() == 0)
return true;
else
return false;
}
if (p.length() == 1 || p[1] != '*') { //對應步驟2,3,4
if (s.size() == 0 || (p[0] != '.' && p[0] != s[0]))
return false;
else
return isMatch(s.substr(1), p.substr(1));
}
while (s.size() != 0 && (s[0] == p[0] || p[0] == '.')) { //對應步驟5,6
if (isMatch(s, p.substr(2)))
return true;
s = s.substr(1);
}
return isMatch(s, p.substr(2));
}
};
現在這個題我還沒有緩過勁兒來,我得再想想。。。