本文共 1904 字,大约阅读时间需要 6 分钟。
为了实现支持 '.' 和 '*' 的正则表达式匹配,我们可以利用动态规划来在 O(n) 的时间复杂度内完成任务,其中 n 是输入字符串的长度。动态规划法能有效处理边界情况,并确保整个输入被完全匹配。
初始化数组:创建一个大小为 n+1
的布尔数组 dp
,其中 dp[i]
表示前 i
个字符是否能够与模式的前 i
个字符完全匹配。初始化 dp[n]
为 true
,表示当输入完全被匹配时,状态为 true
。
从后到前处理模式字符:遍历模式字符串的每个字符,从最后一个字符到第一个字符。根据当前字符的类型,更新 dp
数组:
dp[i-1]
的状态与当前状态合并,确保匹配尽可能多的字符。处理边界情况:确保在处理每个字符之前和之后,状态转移逻辑正确,避免遗漏边界条件。
dp[j]
和 dp[j+1]
都为 true
时,表示当前匹配状态有效。true
。public class Solution { public boolean isMatch(String s, String p) { int n = s.length(); int m = p.length(); // 处理特殊情况:空模式或空字符串不匹配 if (m == 0 || n == 0) { return m == n && p.isEmpty() && s.isEmpty(); } // 创建动态规划数组 boolean[] dp = new boolean[n + 1]; dp[n] = true; // 初始化,全匹配的情况 // 从后向前处理每个字符 for (int j = m - 1; j >= 0; j--) { // 当前字符来自模式 char c = p.charAt(j); // 当前处理的是第j个字符,要影响到dp[j+1] if (c == '*') { // 星号的情况,我们可以把dp[j]设为dp[j] || dp[j+1] dp[j] = dp[j] || dp[j + 1]; } else { // 非星号的情况,只能从前往后检查 if (j + 1 > n) { // 当前处理到字符时,已经超出字符串长度 dp[j] = dp[j + 1]; } else { char sc = s.charAt(j); dp[j] = dp[j + 1] && ((sc == c) || (sc == '.'); // 注意这里的逻辑是当前字符要和模式字符或.匹配 } } } // 处理最后的特殊情况,比如: // 当j =0时,要看是否整个字符串都被匹配 // 特别是,当p不是以星号结尾的时候,可能有的边界情况 return dp[0]; }}
dp
数组,并将最后一个状态设置为 true
,表示输入已完全匹配。dp
数组。true
或 false
。这种方法确保了在每个步骤中正确处理所有可能的匹配情况,从而实现完整的正则表达式匹配。
转载地址:http://vdjez.baihongyu.com/