题目描述
给你一个输入字符串 (s) 和一个字符模式 (p) ,请你实现一个支持 ‘?’ 和 ‘*’ 匹配规则的通配符匹配:
- ‘?’ 可以匹配任何单个字符。
- ‘*’ 可以匹配任意字符序列(包括空字符序列)。
判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而不是部分匹配)。
示例 1:
输入:s = “aa”, p = “a”
输出:false
解释:”a” 无法匹配 “aa” 整个字符串。
示例 2:
输入:s = “aa”, p = ““
输出:true
解释:’‘ 可以匹配任意字符串。
示例 3:
输入:s = “cb”, p = “?a”
输出:false
解释:’?’ 可以匹配 ‘c’, 但第二个 ‘a’ 无法匹配 ‘b’。
提示:
- 0 <= s.length, p.length <= 2000
- s 仅由小写英文字母组成
- p 仅由小写英文字母、’?’ 或 ‘*’ 组成
解决方法
C++
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { public: bool isMatch(string s, string p) { int m = s.length(); int n = p.length(); vector<vector<bool>> dp(m + 1, vector<bool>(n + 1, false)); dp[0][0] = true; for (int j = 1; j <= n; ++j) { if (p[j - 1] == '*') { dp[0][j] = dp[0][j - 1]; } } for (int i = 1; i <= m; ++i) { for (int j = 1; j <= n; ++j) { if (p[j - 1] == s[i - 1] || p[j - 1] == '?') { dp[i][j] = dp[i - 1][j - 1]; } else if (p[j - 1] == '*') { dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; } } } return dp[m][n]; } };
|
结果
执行用时 : 69 ms, 击败 58.85% 使用 C++ 的用户
内存消耗 : 15.31 MB, 击败 39.38% 使用 C++ 的用户
Java
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| public class Solution { public boolean isMatch(String s, String p) { int m = s.length(); int n = p.length(); boolean[][] dp = new boolean[m + 1][n + 1]; dp[0][0] = true; for (int j = 1; j <= n; j++) { if (p.charAt(j - 1) == '*') { dp[0][j] = dp[0][j - 1]; } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (p.charAt(j - 1) == s.charAt(i - 1) || p.charAt(j - 1) == '?') { dp[i][j] = dp[i - 1][j - 1]; } else if (p.charAt(j - 1) == '*') { dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; } } } return dp[m][n]; } }
|
结果
执行用时 : 24 ms, 击败 59.21% 使用 Java 的用户
内存消耗 : 43.70 MB, 击败 56.23% 使用 Java 的用户
Python
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20
| class Solution(object): def isMatch(self, s, p): """ :type s: str :type p: str :rtype: bool """ m, n = len(s), len(p) dp = [[False] * (n + 1) for _ in range(m + 1)] dp[0][0] = True for j in range(1, n + 1): if p[j - 1] == '*': dp[0][j] = dp[0][j - 1] for i in range(1, m + 1): for j in range(1, n + 1): if p[j - 1] == s[i - 1] or p[j - 1] == '?': dp[i][j] = dp[i - 1][j - 1] elif p[j - 1] == '*': dp[i][j] = dp[i - 1][j] or dp[i][j - 1] return dp[m][n]
|
结果
执行用时 : 544 ms, 击败 74.67% 使用 Python 的用户
内存消耗 : 19.36 MB, 击败 78.67% 使用 Python 的用户
Python3
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
| class Solution: def isMatch(self, s: str, p: str) -> bool: m, n = len(s), len(p) dp = [[False] * (n + 1) for _ in range(m + 1)] dp[0][0] = True for j in range(1, n + 1): if p[j - 1] == '*': dp[0][j] = dp[0][j - 1] for i in range(1, m + 1): for j in range(1, n + 1): if p[j - 1] == s[i - 1] or p[j - 1] == '?': dp[i][j] = dp[i - 1][j - 1] elif p[j - 1] == '*': dp[i][j] = dp[i - 1][j] or dp[i][j - 1] return dp[m][n]
|
结果
执行用时 : 399 ms, 击败 79.64% 使用 Python3 的用户
内存消耗 : 24.43 MB, 击败 45.51% 使用 Python3 的用户
C
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| bool isMatch(char* s, char* p) { int m = strlen(s); int n = strlen(p); bool dp[m + 1][n + 1]; memset(dp, false, sizeof(dp)); dp[0][0] = true; for (int j = 1; j <= n; j++) { if (p[j - 1] == '*') { dp[0][j] = dp[0][j - 1]; } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (p[j - 1] == s[i - 1] || p[j - 1] == '?') { dp[i][j] = dp[i - 1][j - 1]; } else if (p[j - 1] == '*') { dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; } } } return dp[m][n]; }
|
结果
执行用时 : 21 ms, 击败 62.82% 使用 C 的用户
内存消耗 : 6.82 MB, 击败 81.41% 使用 C 的用户
C#
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| public class Solution { public bool IsMatch(string s, string p) { int m = s.Length; int n = p.Length; bool[,] dp = new bool[m + 1, n + 1]; dp[0, 0] = true; for (int j = 1; j <= n; j++) { if (p[j - 1] == '*') { dp[0, j] = dp[0, j - 1]; } } for (int i = 1; i <= m; i++) { for (int j = 1; j <= n; j++) { if (p[j - 1] == s[i - 1] || p[j - 1] == '?') { dp[i, j] = dp[i - 1, j - 1]; } else if (p[j - 1] == '*') { dp[i, j] = dp[i - 1, j] || dp[i, j - 1]; } } } return dp[m, n]; } }
|
结果
执行用时 : 65 ms, 击败 93.07% 使用 C# 的用户
内存消耗 : 51.68 MB, 击败 19.80% 使用 C# 的用户
JavaScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26
|
var isMatch = function(s, p) { const m = s.length; const n = p.length; const dp = Array.from({ length: m + 1 }, () => Array(n + 1).fill(false)); dp[0][0] = true; for (let j = 1; j <= n; j++) { if (p[j - 1] === '*') { dp[0][j] = dp[0][j - 1]; } } for (let i = 1; i <= m; i++) { for (let j = 1; j <= n; j++) { if (p[j - 1] === s[i - 1] || p[j - 1] === '?') { dp[i][j] = dp[i - 1][j - 1]; } else if (p[j - 1] === '*') { dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; } } } return dp[m][n]; };
|
结果
执行用时 : 128 ms, 击败 85.29% 使用 JavaScript 的用户
内存消耗 : 66.23 MB, 击败 16.67% 使用 JavaScript 的用户
TypeScript
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
| function isMatch(s: string, p: string): boolean { const m = s.length; const n = p.length; const dp: boolean[][] = Array.from({ length: m + 1 }, () => Array(n + 1).fill(false)); dp[0][0] = true; for (let j = 1; j <= n; j++) { if (p[j - 1] === '*') { dp[0][j] = dp[0][j - 1]; } } for (let i = 1; i <= m; i++) { for (let j = 1; j <= n; j++) { if (p[j - 1] === s[i - 1] || p[j - 1] === '?') { dp[i][j] = dp[i - 1][j - 1]; } else if (p[j - 1] === '*') { dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; } } } return dp[m][n]; }
|
结果
执行用时 : 133 ms, 击败 68.03% 使用 TypeScript 的用户
内存消耗 : 64.14 MB, 击败 12.29% 使用 TypeScript 的用户
PHP
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
| class Solution {
function isMatch($s, $p) { $m = strlen($s); $n = strlen($p); $dp = array_fill(0, $m + 1, array_fill(0, $n + 1, false)); $dp[0][0] = true; for ($j = 1; $j <= $n; $j++) { if ($p[$j - 1] === '*') { $dp[0][$j] = $dp[0][$j - 1]; } } for ($i = 1; $i <= $m; $i++) { for ($j = 1; $j <= $n; $j++) { if ($p[$j - 1] === $s[$i - 1] || $p[$j - 1] === '?') { $dp[$i][$j] = $dp[$i - 1][$j - 1]; } elseif ($p[$j - 1] === '*') { $dp[$i][$j] = $dp[$i - 1][$j] || $dp[$i][$j - 1]; } } } return $dp[$m][$n]; } }
|
结果
执行用时 : 202 ms, 击败 100.00% 使用 PHP 的用户
内存消耗 : 40.62 MB, 击败 100.00% 使用 PHP 的用户
Swift
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class Solution { func isMatch(_ s: String, _ p: String) -> Bool { var target = Array(s), regex = [Character](), flag = false for c in p { if !(c == "*" && flag) { regex.append(c) } flag = c == "*" } var visit = [[Bool]](repeating: [Bool](repeating: false, count: target.count), count: regex.count) var table = [[Bool]](repeating: [Bool](repeating: false, count: target.count), count: regex.count) func memory(_ x: Int, _ y: Int) -> Bool { if x == -1 && y == -1 { return true } else if x == -1 { return false } else if y == -1 { return x == 0 && regex[0] == "*" } else { if !visit[x][y] { table[x][y] = search(x, y) visit[x][y] = true } return table[x][y] } } func search(_ x: Int, _ y: Int) -> Bool { if regex[x] == "?" || regex[x] == target[y] { return memory(x - 1, y - 1) } else if regex[x] == "*" { return memory(x - 1, y) || memory(x, y - 1) } else { return false } } return memory(regex.count - 1, target.count - 1) } }
|
结果
执行用时 : 66 ms, 击败 38.46% 使用 Swift 的用户
内存消耗 : 17.84 MB, 击败 7.69% 使用 Swift 的用户
Kotlin
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| class Solution { fun isMatch(s: String, p: String): Boolean { val m = s.length val n = p.length val dp = Array(m + 1) { BooleanArray(n + 1) } dp[0][0] = true for (j in 1..n) { if (p[j - 1] == '*') { dp[0][j] = dp[0][j - 1] } } for (i in 1..m) { for (j in 1..n) { if (p[j - 1] == s[i - 1] || p[j - 1] == '?') { dp[i][j] = dp[i - 1][j - 1] } else if (p[j - 1] == '*') { dp[i][j] = dp[i - 1][j] || dp[i][j - 1] } } } return dp[m][n] } }
|
结果
执行用时 : 212 ms, 击败 85.71% 使用 Kotlin 的用户
内存消耗 : 36.84 MB, 击败 78.57% 使用 Kotlin 的用户
Dart
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24
| class Solution { bool isMatch(String s, String p) { int m = s.length; int n = p.length; List<List<bool>> dp = List.generate(m + 1, (_) => List<bool>.filled(n + 1, false)); dp[0][0] = true; for (int j = 1; j <= n; ++j) { if (p[j - 1] == '*') { dp[0][j] = dp[0][j - 1]; } } for (int i = 1; i <= m; ++i) { for (int j = 1; j <= n; ++j) { if (p[j - 1] == s[i - 1] || p[j - 1] == '?') { dp[i][j] = dp[i - 1][j - 1]; } else if (p[j - 1] == '*') { dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; } } } return dp[m][n]; } }
|
结果
执行用时 : 356 ms, 击败 -% 使用 Dart 的用户
内存消耗 : 154.70 MB, 击败 100.00% 使用 Dart 的用户
Go
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| func isMatch(s string, p string) bool { m, n := len(s), len(p) dp := make([][]bool, m+1) for i := range dp { dp[i] = make([]bool, n+1) } dp[0][0] = true for j := 1; j <= n; j++ { if p[j-1] == '*' { dp[0][j] = dp[0][j-1] } } for i := 1; i <= m; i++ { for j := 1; j <= n; j++ { if p[j-1] == s[i-1] || p[j-1] == '?' { dp[i][j] = dp[i-1][j-1] } else if p[j-1] == '*' { dp[i][j] = dp[i-1][j] || dp[i][j-1] } } } return dp[m][n] }
|
结果
执行用时 : 3 ms, 击败 97.78% 使用 Go 的用户
内存消耗 : 6.34 MB, 击败 43.33% 使用 Go 的用户
Ruby
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
|
def is_match(s, p) m, n = s.length, p.length dp = Array.new(m + 1) { Array.new(n + 1, false) } dp[0][0] = true (1..n).each do |j| dp[0][j] = dp[0][j - 1] if p[j - 1] == '*' end (1..m).each do |i| (1..n).each do |j| if p[j - 1] == s[i - 1] || p[j - 1] == '?' dp[i][j] = dp[i - 1][j - 1] elsif p[j - 1] == '*' dp[i][j] = dp[i - 1][j] || dp[i][j - 1] end end end dp[m][n] end
|
结果
执行用时 : 1296 ms, 击败 100.00% 使用 Ruby 的用户
内存消耗 : 231.35 MB, 击败 100.00% 使用 Ruby 的用户
Scala
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23
| object Solution { def isMatch(s: String, p: String): Boolean = { val m = s.length val n = p.length val dp = Array.ofDim[Boolean](m + 1, n + 1) dp(0)(0) = true for (j <- 1 to n) { if (p(j - 1) == '*') { dp(0)(j) = dp(0)(j - 1) } } for (i <- 1 to m) { for (j <- 1 to n) { if (p(j - 1) == s(i - 1) || p(j - 1) == '?') { dp(i)(j) = dp(i - 1)(j - 1) } else if (p(j - 1) == '*') { dp(i)(j) = dp(i - 1)(j) || dp(i)(j - 1) } } } dp(m)(n) } }
|
结果
执行用时 : 554 ms, 击败 100.00% 使用 Scala 的用户
内存消耗 : 55.13 MB, 击败 100.00% 使用 Scala 的用户
Rust
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| impl Solution { pub fn is_match(s: String, p: String) -> bool { let m = s.len(); let n = p.len(); let mut dp = vec![vec![false; n + 1]; m + 1]; dp[0][0] = true; for j in 1..=n { if p.chars().nth(j - 1).unwrap() == '*' { dp[0][j] = dp[0][j - 1]; } } for i in 1..=m { for j in 1..=n { if p.chars().nth(j - 1).unwrap() == s.chars().nth(i - 1).unwrap() || p.chars().nth(j - 1).unwrap() == '?' { dp[i][j] = dp[i - 1][j - 1]; } else if p.chars().nth(j - 1).unwrap() == '*' { dp[i][j] = dp[i - 1][j] || dp[i][j - 1]; } } } dp[m][n] } }
|
结果
执行用时 : 998 ms, 击败 6.67% 使用 Rust 的用户
内存消耗 : 2.82 MB, 击败 20.00% 使用 Rust 的用户
Racket
暂时未解决
结果
执行用时 : ms, 击败 % 使用 Racket 的用户
内存消耗 : MB, 击败 % 使用 Racket 的用户
Erlang
暂时未解决
结果
执行用时 : ms, 击败 % 使用 Erlang 的用户
内存消耗 : MB, 击败 % 使用 Erlang 的用户
Elixir
暂时未解决
结果
执行用时 : ms, 击败 % 使用 Elixir 的用户
内存消耗 : MB, 击败 % 使用 Elixir 的用户