【leetCode】44_萬用字元匹配
阿新 • • 發佈:2018-12-14
dp:
class Solution { public: bool isMatch(string s, string p) { //tag 用於dp,tag[i][j]代表s的子串s[0,i-1] 可以匹配 p的子串p[0,j-1]。 bool ** tag = new bool*[s.length() + 1]; for (int i = 0; i <= s.length(); i ++){ tag[i] = new bool [p.length() + 1]; memset(tag[i], 0, sizeof(bool) * (p.length() + 1)); } //tag[0][0]初始化條件,可以理解成,s和p的子串s[0,-1], p[0,-1]匹配,即兩個空串匹配。 tag[0][0] = true; //dp的遞推方程是:tag[i][j] = // (1)p[j - 1] == '*', 則為:tag[i - 1][j - 1] || tag[i][j - 1] || tag[i - 1][j]; // (2)為:tag[i - 1][j - 1] && (p[j - 1] == '?' ? 1: p[j - 1] == s[i - 1]) for (int j = 1; j <= p.length(); j ++){ for (int i = 0; i <= s.length(); i ++){ if (p[j - 1] == '*'){ tag[i][j] = (i > 0 ? (tag[i - 1][j - 1]||tag[i - 1][j]): 0) || tag[i][j - 1]; } else if (i != 0){ tag[i][j] = tag[i - 1][j - 1] && (p[j - 1] == '?' ? 1: p[j - 1] == s[i - 1]); } } } return tag[s.length()][p.length()]; } };
帶回溯的貪心:
思路是*字元匹配的時候,可以匹配0~無窮多個字元。所以,列舉s串被匹配的字元數量。
方法是匹配到*的時候,記錄下s和p的位置s*和p*,給p的位置+1, s位置不變,此時*匹配0個字元,然後s和p繼續匹配之後的字串。如果匹配不成功,回溯,p的匹配位置更改回p*+1,s的位置更改為記錄s*+1,此時*匹配1個字元,然後s和p繼續匹配之後的字元。依此類推。
class Solution { public: bool isMatch(string s, string p) { int scur = 0, pcur = 0, sstar = -1, pstar = -1; while(scur != s.length()){ if (s[scur] == p[pcur] || p[pcur] == '?'){ scur ++; pcur ++; } else if (p[pcur] == '*'){ pstar = pcur ++; sstar = scur; } else if (pstar != -1){ pcur = pstar + 1; scur = ++ sstar; } else{ return false; } } while (p[pcur] == '*'){ pcur ++; } return pcur == p.length(); } };