LeetCode 题解(108): Wildcard Matching

来源:互联网 发布:电脑淘宝怎么发送链接 编辑:程序博客网 时间:2024/05/21 06:46

题目:

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

题解:

解法一: 先用动态规划法。用一维列向量查表。

        ""    a    *    ?

“”     1    0    0    0

a     0    1    1    0

b     0    0    1    1

c     0    0    1    1

上图由左列向右列计算,每列计算时如果为字符或?,需要从底部向顶部计算。class Solution:
注意代码中用count计算非“*”字符的部分,以及用last变量记录上一列第一个true出现的位置的部分,如果不使用这两部分,会超时。

C++版:

public boolean isMatch(String s, String p) {        boolean[] test = new boolean[s.length() + 1];        test[0] = true;        int count = 0;        for(int i = 0; i < p.length(); i++) {            if(p.charAt(i) != '*')                count++;        }        if(count > s.length())            return false;                int last = 0;        for(int i = 0; i < p.length(); i++) {            int temp = last;            last = test.length;            if(p.charAt(i) != '*') {                for(int j = test.length - 1; j > 0; j--) {                    if(test[j - 1] && ((p.charAt(i) != '?' && p.charAt(i) == s.charAt(j - 1)) || (p.charAt(i) == '?'))) {                        test[j] = true;                        last = j;                    } else {                        test[j] = false;                    }                }                test[0] = false;            } else {                last = temp;                for(int j = 0; j < test.length; j++) {                    if(j >= temp)                        test[j] = true;                    else                        test[j] = false;                }            }        }        return test[test.length - 1];    }

Java版:

public class Solution {    public boolean isMatch(String s, String p) {        boolean[] test = new boolean[s.length() + 1];        test[0] = true;        int count = 0;        for(int i = 0; i < p.length(); i++) {            if(p.charAt(i) != '*')                count++;        }        if(count > s.length())            return false;                int last = 0;        for(int i = 0; i < p.length(); i++) {            int temp = last;            last = test.length;            if(p.charAt(i) != '*') {                for(int j = test.length - 1; j > 0; j--) {                    if(test[j - 1] && ((p.charAt(i) != '?' && p.charAt(i) == s.charAt(j - 1)) || (p.charAt(i) == '?'))) {                        test[j] = true;                        last = j;                    } else {                        test[j] = false;                    }                }                test[0] = false;            } else {                last = temp;                for(int j = 0; j < test.length; j++) {                    if(j >= temp)                        test[j] = true;                    else                        test[j] = false;                }            }        }        return test[test.length - 1];    }}

Python版:

class Solution:    # @param {string} s    # @param {string} p    # @return {boolean}    def isMatch(self, s, p):        count = 0        for i in p:            if i != '*':                count += 1        if count > len(s):            return False        test = [False] * (len(s) + 1)        test[0] = True        last = 0        for i in p:            temp = last            if i != '*':                last = len(test)                for j in reversed(range(1, len(test))):                    if test[j - 1] and ((i == '?') or (i != '?' and s[j - 1] == i)):                        test[j] = True                        last = j                    else:                        test[j] = False                test[0] = False            else:                last = temp                for j in range(0, len(test)):                    if j >= temp:                        test[j] = True                    else:                        test[j] = False        return test[len(test) - 1]

解法二: 不太直观的贪心算法。

如果为字符且匹配,继续比较下一个。如果为?,继续比较下一个。如果为*, 记录*的位置,比较当前S字符与下一个P字符,如果匹配,继续比较下一个,如果不匹配,S++,P = star + 1.

C++版:

class Solution {public:    bool isMatch(string s, string p) {        int i = 0, j = 0, star = -1, mark = 0;        while(i < s.length()) {            if(p[j] != '*' && (p[j] == '?' || (p[j] != '?' && p[j] == s[i]))) {                i++;                j++;            } else if(p[j] == '*') {                star = j++;                mark = i;            } else if(star != -1) {                j = star + 1;                i = ++mark;            } else {                return false;            }        }        while(j < p.length() && p[j] == '*')            j++;        return j == p.length();    }};

Java版:

public class Solution {    public boolean isMatch(String s, String p) {        int i = 0, j = 0, star = -1, mark = 0;        while(i < s.length()) {            if(j < p.length() && (p.charAt(j) == '?' || (p.charAt(j) != '*' && p.charAt(j) == s.charAt(i)))) {                i++;                j++;            } else if(j < p.length() && p.charAt(j) == '*') {                mark = i;                star = j++;            } else if(star != -1) {                i = ++mark;                j = star + 1;            } else {                return false;            }        }        while(j < p.length() && p.charAt(j) == '*')            j++;        return j == p.length();    }}

Python版:

class Solution:    # @param {string} s    # @param {string} p    # @return {boolean}    def isMatch(self, s, p):        i, j, star, mark = 0, 0, -1, 0        while i < len(s):            if j < len(p) and (p[j] == '?' or (p[j] != '*' and p[j] == s[i])):                i += 1                j += 1            elif j < len(p) and p[j] == '*':                mark = i                star = j                j += 1            elif star != -1:                mark += 1                i = mark                j = star + 1            else:                return False        while j < len(p) and p[j] == '*':            j += 1        return j == len(p)


0 0