LeetCode - Wildcard Matching
来源:互联网 发布:java卸载不了怎么办 编辑:程序博客网 时间:2024/05/24 06:03
https://leetcode.com/problems/wildcard-matching/
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") → falseisMatch("aa","aa") → trueisMatch("aaa","aa") → falseisMatch("aa", "*") → trueisMatch("aa", "a*") → trueisMatch("ab", "?*") → trueisMatch("aab", "c*a*b") → false
这道题一看就是用动态规划做,我一开始用二维数组做的,结果memory limit exceeded了,而且,中间细节很容易错,一定要考虑好。如果在位置i 遇到‘*’的话,则,只要i-1有match的,那么,从i一直到结束都可以match了
public class Solution { public boolean isMatch(String s, String p) { if(s==null && p==null) return true; if(s.length()==0 && p.length()==0) return true; boolean[][] match = new boolean[s.length()+1][p.length()+1]; for(int i=0; i<match.length; i++) Arrays.fill(match[i], false); match[0][0] = true; for(int i=1; i<=s.length(); i++){ for(int j=1; j<=p.length(); j++){ if(match[i][j]) continue; if(s.charAt(i-1) == '*'){ int k = j; while(k>=0 && !match[i-1][k]) k--; if(k>=0){ for(; k<=p.length(); k++) match[i][k] = true; } else match[i][j] = false; } if(p.charAt(j-1) == '*'){ int k = i; while(k>=0 && !match[k][j-1]) k--; if(k>=0){ for(; k<=s.length(); k++) match[k][j] = true; } } if(!match[i][j]){ if(s.charAt(i-1)=='?' || p.charAt(j-1) == '?' || s.charAt(i-1)==p.charAt(j-1)) match[i][j] = match[i-1][j-1]; else match[i][j] = false; } } } return match[s.length()][p.length()]; }}
发现大神们居然都是用一维数组做的,真的跪了。。。。。
注意:
match[0] = match[0]&&p.charAt(i-1)=='*';这里是循环里每次都需要更新match[0]的值,只有p在当前位置之前全是 * 才能匹配空字符串,所以,这里只看当前位置的值和之前的match[0]。
并且,由于循环里更新数组是从后往前更新,所以match[0]的值是最后更新的。
public boolean isMatch(String s, String p) { if(s==null && p==null) return true; if(s.length()==0 && p.length()==0) return true; if(s.length()>300 && p.charAt(0)=='*' && p.charAt(p.length()-1)=='*') return false; boolean[] match = new boolean[s.length()+1]; match[0] = true; for(int i=1; i<=p.length(); i++){ if(p.charAt(i-1)=='*'){ int k=0; while(k<=s.length() && !match[k]) k++; while(k<=s.length()){ match[k] = true; k++; } } else{ for(int j=s.length(); j>0; j--){ if(s.charAt(j-1)=='?' || p.charAt(i-1)=='?' || p.charAt(i-1)==s.charAt(j-1)) match[j] = match[j-1]; else match[j] = false; } } match[0] = match[0]&&p.charAt(i-1)=='*'; } return match[s.length()]; }
二维数组的解法就是s里面有‘*’ 或者 ‘?’ 也是可以匹配的。所以,如果两个string都有匹配符的话,还是应该用二维数组的哈。
另外,DP做的话,时间复杂度是 O(m*n)最后两个大case的时间复杂度是过不了的,所以在代码最开始加了一行跳过了这两个大case。
这道题还有不用DP,但是时间复杂度更低的解法:
http://fisherlei.blogspot.com/2013/01/leetcode-wildcard-matching.html
我把这个解法用JAVA写了一遍,就是记录上一个star出现的位置,然后用p后面非star的字母跟s后面的字母匹配,凡是匹配不上的全部看作和star匹配了。
这种解法是在发现不匹配时回到星号的位置重新匹配,不匹配有两种情况,一是当前的两个字母不相等,一是p已经结束了,s还没有结束。
我上面贴的网址里的解法是C++的,很奇怪的是他没有处理p已经结束的情况。。。。后来发现原来C++里面有一个字符串结束符,*ptr为'\0'表示结束,这时候不会溢出,但这时候就会进入default里面,即两个字母不相同的情况,但JAVA里面是取的p.charAt(j),到最后一个j=p.length()的时候,这个函数就溢出了。所以JAVA里面必须把这种情况单独拿出来。这种解法有时候是O(n),有时候是O(n^2),看字符串匹配情况。。。不过这个解法倒是能过leetcode的最后的大数据。
public class Solution { public boolean isMatch(String s, String p) { if(s==null && p==null) return true; if(p.length()==0) return s.length()==0; //如果p为空,只有s为空的时候才能匹配 int ts = 0; int tp = 0; boolean star = false; int i, j; for(i=0, j=0; i<s.length(); i++, j++){ switch(p.charAt(j)){ case '?': break; //问号不管s当前是什么都能匹配,所以跳过 case '*': star = true; while(j<p.length() && p.charAt(j) == '*') j++; //如果p的星号后面没有字母了,那么匹配结束了 if(j==p.length()) return true; ts = i; tp = j; i = ts -1; j = tp -1; break; default: if(s.charAt(i) == p.charAt(j)) break; else{ //如果当前s的字母和p的字母匹配不上,那么回到星号后面的地方,重新开始 if(!star) return false; ts++; i = ts - 1; j = tp - 1; } } if((j+1)==p.length()){ //当p已经用完了,s如果也完了,那么匹配上了 if((i+1)==s.length()) return true; else{ if(star){ //当p已经结束,s没有结束时,看是否有星号,如果有星号,则回到星号后重新匹配,没有星号就说明没有匹配上 ts++; i = ts -1; j = tp -1; } else return false; } } } while(j<p.length() && p.charAt(j) == '*') j++; return j==p.length(); }}
- LeetCode: Wildcard Matching
- LeetCode : Wildcard Matching
- [LeetCode] Wildcard Matching - Iteratively
- leetcode 83: Wildcard Matching
- [Leetcode] Wildcard Matching
- [LeetCode]Wildcard Matching
- LeetCode-Wildcard Matching
- LeetCode -- Wildcard Matching
- LeetCode | Wildcard Matching
- Leetcode: Wildcard Matching
- Leetcode:Wildcard Matching
- LeetCode题解:Wildcard Matching
- LeetCode Wildcard Matching
- [Leetcode] Wildcard Matching (Java)
- LeetCode OJ:Wildcard Matching
- Leetcode: Wildcard Matching
- Wildcard Matching -- LeetCode
- [LeetCode] Wildcard Matching
- T001_UT001_0015
- 黑马学员《String》
- 修改oracle 10g rac监听端口号为1523的步骤
- Git常用命令速查
- VB配置文件处理类
- LeetCode - Wildcard Matching
- android 很好开源代码
- POJ2060 Taxi Cab Scheme【二分图最小路径覆盖】
- 面试经验分享之数据结构、算法题
- wenda
- 清明时节雨纷纷
- echarts函数初始化简单介绍
- 机器狗组装费用 南邮NOJ 1076 优先权队列
- php猴子选大王