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
Solution:
Method 1: Two Pointers
We use two pointers.
One points to the string and one points to the pattern.
When we find a '?' in the pattern, we advance two pointers.
When we find a '*' in the pattern, we mark the current index of the string and the current index of the '*'. And start to do the match from mark and star + 1.
If we cannot find match, we go back to mark + 1 and star + 1 and try to match. (Every time we backtrack, we need to increase mark by 1.)
Worst case time complexity is O(mn).
The space complexity is O(1).
Code:
public class Solution { public boolean isMatch(String s, String p) { int i = 0; int j = 0; int mark = 0; int star = -1; while (i < s.length()) { if (j < p.length() && (s.charAt(i) == p.charAt(j) || p.charAt(j) == '?')) { i++; j++; } else if (j < p.length() && p.charAt(j) == '*') { mark = i; star = j; j++; } else if (star != -1) { mark++; i = mark; j = star + 1; } else { return false; } } while (j < p.length() && p.charAt(j) == '*') { j++; } return j == p.length(); } }
Method 2: Dynamic Programming
Code: