[Leetcode]_44 Wildcard Matching
阿新 • • 發佈:2019-01-27
/**
* Index: 44
* Title: Wildcard Matching
* Author: ltree98
**/
題意
字串匹配
Note:
- ‘?’ 可匹配任意一個字元(且必須匹配一個字元)
- ‘*’ 可匹配任意長度字元(包括空串)
我的
思路
動態規劃,
二維陣列,以s串為行,p串為列;
dp[i][j] 表示 0i的s串能否與0j的p串匹配成功。
推倒公式為:
- p[j]為 ‘*’,dp[i][j] = dp[i-1][j-1] || dp[i][j-1] || dp[i-1][j]
- p[j]為 ‘?’,dp[i][j] = dp[i-1][j-1] && true
- p[j]為 ‘a’~‘z’,dp[i][j] = dp[i-1][j-1] && (s[i] == p[j])
注意處理空串輸入情況。
時間複雜度:O(m * n)
空間複雜度:O(m * n)
實現
class Solution { public: bool isMatch(string s, string p) { if(p.empty()) return s.empty(); vector<vector<bool>> dp(s.length()+1, vector<bool>(p.length()+1, false)); dp[0][0] = true; for(int i = 1; i <= p.length(); i++) { if(p[i-1] != '*') break; dp[0][i] = true; } for(int i = 1; i <= s.length(); i++) { for(int j = 1; j <= p.length(); j++) { if(p[j-1] == '*') { dp[i][j] = dp[i-1][j-1] || dp[i][j-1] || dp[i-1][j]; } else if(p[j-1] == '?') { dp[i][j] = dp[i-1][j-1]; } else { dp[i][j] = dp[i-1][j-1] && s[i-1] == p[j-1]; } } } return dp[s.length()][p.length()]; } };
進階
思路
深度優先搜尋
有減枝,所以時間可以小於 O(m * n)
實現
C++版本,作者:Hanafubuki
class Solution { // return value: // 0: reach the end of s but unmatched // 1: unmatched without reaching the end of s // 2: matched int dfs(string& s, string& p, int si, int pi) { if (si == s.size() and pi == p.size()) return 2; if (si == s.size() and p[pi] != '*') return 0; if (pi == p.size()) return 1; if (p[pi] == '*') { if (pi+1 < p.size() and p[pi+1] == '*') return dfs(s, p, si, pi+1); // skip duplicate '*' for(int i = 0; i <= s.size()-si; ++i) { int ret = dfs(s, p, si+i, pi+1); if (ret == 0 or ret == 2) return ret; } } if (p[pi] == '?' or s[si] == p[pi]) return dfs(s, p, si+1, pi+1); return 1; } public: bool isMatch(string s, string p) { return dfs(s, p, 0, 0) > 1; } };