力扣题目
解题思路
java代码
力扣题目:
给你一个输入字符串 (s
) 和一个字符模式 (p
) ,请你实现一个支持 '?'
和 '*'
匹配规则的通配符匹配:
'?'
可以匹配任何单个字符。'*'
可以匹配任意字符序列(包括空字符序列)。
判定匹配成功的充要条件是:字符模式必须能够 完全匹配 输入字符串(而不是部分匹配)。
示例 1:
输入:s = "aa", p = "a" 输出:false 解释:"a" 无法匹配 "aa" 整个字符串。
示例 2:
输入:s = "aa", p = "*" 输出:true 解释:'*' 可以匹配任意字符串。
示例 3:
输入:s = "cb", p = "?a" 输出:false 解释:'?' 可以匹配 'c', 但第二个 'a' 无法匹配 'b'。
解题思路:
算法原理:
这道题使用动态规划来判断给定的字符串 s
是否与模式字符串 p
匹配。
思路:
- 创建一个二维布尔型的
dp
数组,dp[i][j]
表示s
的前i
个字符和p
的前j
个字符是否匹配。 - 初始化
dp[0][0]
为true
,表示空字符串和空模式匹配。然后处理模式开头为连续*
的情况,将对应的dp[0][j]
设为true
。 - 对于非空字符串和模式的匹配情况:
- 如果模式字符是
*
,则当前状态取决于两种情况:一是忽略*
及其前面的字符(dp[i][j - 1]
),二是将*
视为匹配s
中的一个字符(dp[i - 1][j]
)。 - 如果模式字符是
?
或者与字符串中的字符相同,则取决于前一个字符的匹配情况(dp[i - 1][j - 1]
)。
- 如果模式字符是
- 最终返回
dp[m][n]
,其中m
是字符串s
的长度,n
是模式字符串p
的长度。
代码分析:
- 首先进行边界情况的初始化。
- 然后通过两层循环遍历字符串和模式,根据模式字符的不同情况更新
dp
数组的值。
时间复杂度:O(mn),其中 m
是字符串 s
的长度,n
是模式字符串 p
的长度。
空间复杂度:O(mn),用于存储 dp
数组。
java代码:
package com.example.lib;
public class Leetcode44 {
private static final char DOT = '?';
public static void main(String[] args) {
System.out.println(new Leetcode44().isMatch("aa", "*"));
}
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 i = 1; i <= n; ++i) {
if (p.charAt(i - 1) == '*') {
dp[0][i] = true;
} else {
break;
}
}
for (int i = 1; i <= m; ++i) {
for (int j = 1; j <= n; ++j) {
if (p.charAt(j - 1) == '*') {
dp[i][j] = dp[i][j - 1] || dp[i - 1][j];
} else if (p.charAt(j - 1) == '?' || s.charAt(i - 1) == p.charAt(j - 1)) {
dp[i][j] = dp[i - 1][j - 1];
}
}
}
return dp[m][n];
}
}
更多详细内容同步到公众号,感谢大家的支持!
每天都会给刷算法的小伙伴推送明日一题,并且没有任何收费项