您的位置:首页 > 其它

(细节题)[LeetCode]Wildcard Matching

2016-10-17 15:17 399 查看
Question

Implement wildcard pattern matching with support for ‘?’ and ‘*’.

‘?’ Matches any single character.

‘*’ Matches any sequence of characters (including the empty sequence).

The matching should cover the entire input string (not partial).

The function prototype should be:

bool isMatch(const char *s, const char *p)

Some examples:

isMatch(“aa”,”a”) → false

isMatch(“aa”,”aa”) → true

isMatch(“aaa”,”aa”) → false

isMatch(“aa”, “*”) → true

isMatch(“aa”, “a*”) → true

isMatch(“ab”, “?*”) → true

isMatch(“aab”, “c*a*b”) → false

本题难度Hard。

双指针法

【复杂度】

时间 O(N) 空间 O(1)

【思路】

本题就是个细节题。

假设我们用两个指针分别指向s和p字符串中要匹配的位置,首先分析下通配符匹配过程中会有哪些情况是成功:

1、s的字符和p的字符相等

2、p中的字符是
?
,这时无论s的字符是什么都可以匹配一个

3、p中遇到了一个
*
,这时无论s的字符是什么都没关系

4、之前的都不符合,但是p在之前的位置有一个
*
,我们可以从上一个
*
后面开始匹配

5、s已经匹配完,但是p后面还有很多连续的
*


这里1和2的情况比较好处理,关键在于如何处理3和4的情况。当我们遇到一个
*
时,因为之后可能要退回至该位置重新匹配,我们要将它的下标记录下来,比如
idxstar
。但是,当我们连续遇到两次4的情况,如何保证我还是能继续匹配s,而不是每次都退回
idxstar+1
导致循环呢?所以我们还要记录一个
idxmatch
,用来记录用上一个
*
连续匹配到的s中的下标。最后,对于情况5,我们用一个循环跳过末尾的
*
跳过就行了。

【附】

用dfs的方法可以解决,但是超时。

【代码】

public class Solution {
public boolean isMatch(String s, String p) {
int idxs = 0, idxp = 0, idxstar = -1, idxmatch = 0;
while(idxs < s.length()){
// 当两个指针指向完全相同的字符时,或者p中遇到的是?时
if(idxp < p.length() && (s.charAt(idxs) == p.charAt(idxp) || p.charAt(idxp) == '?')){
idxp++;
idxs++;
// 如果字符不同也没有?,但在p中遇到是*时,我们记录下*的位置,但不改变s的指针
} else if(idxp < p.length() && p.charAt(idxp)=='*'){
idxstar = idxp;
idxp++;
//遇到*后,我们用idxmatch来记录*匹配到的s字符串的位置,和不用*匹配到的s字符串位置相区分
idxmatch = idxs;
// 如果字符不同也没有?,p指向的也不是*,但之前已经遇到*的话,我们可以从idxmatch继续匹配任意字符
} else if(idxstar != -1){
// 用上一个*来匹配,那我们p的指针也应该退回至上一个*的后面
idxp = idxstar + 1;
// 用*匹配到的位置递增
idxmatch++;
// s的指针退回至用*匹配到位置
idxs = idxmatch;
} else {
return false;
}
}
// 因为1个*能匹配无限序列,如果p末尾有多个*,我们都要跳过
while(idxp < p.length() && p.charAt(idxp) == '*'){
idxp++;
}
// 如果p匹配完了,说明匹配成功
return idxp == p.length();
}
}


参考

[Leetcode] Wildcard Matching 通配符匹配
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  leetcode