這道題做了很久,沒做出來,卡在*的狀態轉移上。
狀態定義dp[i][j],下標個數,表示從字串s的第i個字元及之前和模式串p的第j個字元及之前是否匹配。這裡為什麼要用個數,因為要考慮空的情況,用開始位置0來表示空,為什麼要考慮空的情況,因為狀態轉移需要上一行和本行的左邊。
初始狀態需要考慮*和空的情況,因為開頭多個連續*也是和空匹配的。
這裡有乙個trick,不用考慮狀態是否為1,直接使用賦值,這樣減少了**複雜,因為0賦值還是0,不用先判斷狀態是否匹配。
狀態轉移:
如果遇到s字元和p字元相同或者p字元是'.',說明兩個字元匹配,相當於字串匹配同時前進1,所以和dp[i-1][j-1]相同。
這裡是重點,沒想出來的地方:如果p字元是*,說明匹配前乙個字元的0次或者多個,有3種情況:
1.不要這個c*,dp[i][j-2],i是因為狀態定義是已經匹配的,這裡我們沒有匹配任何模式,沒有增加匹配新的字元。
2.把c*看作是c,就是只要乙個字元,這個是因為c*有2個字元,如果只有乙個字元的情況,多出了乙個*,所以需要忽略*,值和上乙個一樣,dp[i][j-1]
3.有多個字元,所以是dp[i-1][j],因為上乙個相同字元的時候已經到達了j。
最後,是或操作,就是可以從這三個地方轉移過來,和列舉差不多。
class solution
for(int i=1;i<=s.size();i++)
else if(p[j-1]=='*')
else
dp[i][j]=dp[i][j-2];}}
}return dp[s.size()][p.size()];
}};
由於看作是乙個單位,所以沒有第二步。
class solution ;
bool ismatch(string s, string p)
node node;
node.c=p[i];
node.has_star=has_star;
pattern.push_back(node);
if(has_star)
i+=2;
else
i+=1;
}int dp[s.size()+1][pattern.size()+1];
memset(dp,0,sizeof(dp));
dp[0][0]=1;
for(int j=1;j<=pattern.size();j++)
else
break;
}for(int i=1;i<=s.size();i++)
}else if(has_star)}}
return dp[s.size()][pattern.size()];
}};
LeetCode10 正規表示式
給你乙個字串 s 和乙個字元規律 p,請你來實現乙個支援 和 的正規表示式匹配。匹配任意單個字元 匹配零個或多個前面的那乙個元素 所謂匹配,是要涵蓋 整個 字串 s的,而不是部分字串。說明 s 可能為空,且只包含從 a z 的小寫字母。p 可能為空,且只包含從 a z 的小寫字母,以及字元 和 示例...
LeetCode 10 正規表示式匹配
實現支援 和 的正規表示式匹配。匹配任意單個字元。匹配零個或多個前面的元素。匹配應該覆蓋整個輸入字串 不是部分字串 函式 bool ismatch const char s,const char p 例子 ismatch aa a false ismatch aa aa true ismatch a...
leetCode 10 正規表示式匹配
這道題花了功夫,所以把想到的的寫下來。這個要從字串的屁股開始匹配。道理很簡單,從正面匹配,匹配的方式很多,需要全部列舉,不利於縮小問題規模,舉個例子,aac和a a a c,從正面開始匹配,從全部需要列舉的匹配情況中舉幾個例子 aac匹配a a a c,匹配a a a c,匹配a a a c。從屁股...