***leetCode-Regular Expression Matching-javascript
阿新 • • 發佈:2018-12-15
Regular Expression Matching(正則表示式匹配)
題目大意:輸入字串 (s) 和模式串 §, 實現正則表示式匹配, 支援 ‘.’ and ‘’。
‘.’ 匹配任意單個字元
'’ 匹配0個或多個與前一個字元相同的字元。
注意:必須是全部匹配才算匹配,部分匹配不算
Note:
s可以為空且只含小寫字元a-z.
p可以為空且只含小寫字元a-z 和字元 . 或 *
樣例輸入:
s = “ab”
p = “.*”
輸出: true
解釋: “.*” 意味著0個或多個任意字元.
程式碼思路: 1.最好的情況:不含 * 號,則從頭匹配到尾即可 2.含 * 的情況: 2.1 匹配0個與*號前一個字元相同的字元(即刪除這兩個字元)後能否匹配成功。 2.2 若當前字元相等,匹配+1個 與*號前一個字元(即當前字元)相同的字元後能否匹配成功。
//遞迴實現
var isMatch = function(s, p) {
let sLen=s.length,pLen=p.length;
if(pLen==0){ return sLen==pLen;} //如果模式串為空
let first=(sLen!=0 && (s[0]==p[0] || p[0]=='.')); //兩個字串都不為空,且首字元相等
if(pLen>=2 && p[1]=='*'){ //模式串長度>2 且第二個字元為*
//去除前兩個字元後能匹配上 或者 將*變成前面字元後能匹配上
return (isMatch(s,p.substring(2)) || (first && isMatch(s.substring(1),p)));
}else{ //模式串長度為1
return first && isMatch(s.substring(1),p.substring(1)); //匹配下一個字元
}
};
/**
* @param {string} s
* @param {string} p
* @return {boolean}
*/
//DP實現,基於上面的遞迴,但是比純遞迴快很多
var DP;
var dp = function (i,j,s, p) {
let sLen=s.length,pLen=p.length;
if(DP[i][j]!=undefined){ return DP[i][j]==true;} //如果有一個字串為空
let ans;
if(j==p.length){ ans=(i==sLen);}
else {
let first=(i<sLen && (s[i]==p[j] || p[j]=='.'));
if((j+1)<pLen && p[j+1]=='*'){
ans=(dp(i,j+2,s,p) || (first && dp(i+1,j,s,p)));
}else{
ans=first && dp(i+1,j+1,s,p);
}
}
DP[i][j]=ans ? true : false;
return ans;
};
function isMatch(s,p){
DP=new Array(s.length+1);
for(let i=0;i<=s.length;i++){
DP[i]=new Array(p.length+1);
}
return dp(0,0,s,p);
}