leetcode 44 字符匹配

题意:s是空串或包含a-z字母;

p为包含a-z字母或?或 * (其中*可以匹配任意字符串包括空串,?可以匹配任意字符)。

思路:

1)特殊情况:当s为空串时,p为连续 * 时,则连续 * 的位置都为true。

2)若p的第j个字符为 * ,分两种情况:

a)  若p中的前 j-1个字符和 s 中的前 i 个字符匹配成功了, 即 dp[i][j-1] == true , 因为 * 可以匹配空串,则 dp[i][j] == true;

b)  若p中的前 j 个字符和 s 中前 i-1 个字符匹配成功了,即 dp[i-1][j] == true , 因为 * 可以匹配任意字符串,则 dp[i][j] == true.

3)   若p中的第j个字符不是 * 时,则需要满足 dp[i-1][j-1] == true 和 s 中的第i个字符和p中的第j个字符相等, 即 s[i-1] == p[j-1], 或者 p中的第j个字符是问号, 即 p[j-1] == ‘?‘ 则 dp[i][j] == true.

注意:dp[][] 初始化申请空间大小要为 (m+1, n+1) ,因为dp[0][0] 为p和s为空串时候的情况。

dp如果用二维数组定义会超时!所以用二维vector。

注:s[i-1] 代表s中第i位字符。

class Solution {
public:
    bool isMatch(string s, string p) {

        int m = s.size();
        int n = p.size();
        //dp[i][j]:s中前i个字符组成的子串和p中前j个字符组成的子串是否能匹配
        //bool dp[m+1][n+1] = {false};
        vector<vector<bool> > dp(m+1, vector<bool>(n+1, false));
        //s,p都为空,返回0
        dp[0][0] = true;

        //s为空, p为连续星号时,赋值为true
        for(int i = 1; i <= n; i++){
            if(p[i-1] == ‘*‘)
                dp[0][i] = dp[0][i-1];
        }

        for(int i=1; i<=m; i++){
            for(int j=1; j<=n; j++){
                if(p[j-1] == ‘*‘)
                    dp[i][j] = dp[i-1][j] || dp[i][j-1];
                else
                    dp[i][j] = (s[i-1]==p[j-1] || p[j-1] == ‘?‘) && dp[i-1][j-1];
            }
        }
        return dp[m][n];

    }
};

原文地址:https://www.cnblogs.com/Bella2017/p/10644299.html

时间: 2024-10-13 04:57:49

leetcode 44 字符匹配的相关文章

LeetCode 44. 通配符匹配

给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配. '?' 可以匹配任何单个字符. '*' 可以匹配任意字符串(包括空字符串). 两个字符串完全匹配才算匹配成功. 说明: s 可能为空,且只包含从 a-z 的小写字母. p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *. 示例 1: 输入: s = "aa" p = "a" 输出: false 解释: "a" 无法匹配 "

LeetCode 44. 通配符匹配(Wildcard Matching)

题目描述 给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配. '?' 可以匹配任何单个字符. '*' 可以匹配任意字符串(包括空字符串). 两个字符串完全匹配才算匹配成功. 说明: s 可能为空,且只包含从 a-z 的小写字母. p 可能为空,且只包含从 a-z 的小写字母,以及字符 ? 和 *. 示例 1: 输入: s = "aa" p = "a" 输出: false 解释: "a" 无法匹配 &

leetcode 44 通配符匹配(dp)

思路: 思路一: 利用两个指针进行遍历. 在代码里解释. 时间复杂度为:O(mn)O(mn)O(mn) 思路二: 动态规划 dp[i][j]表示s到i位置,p到j位置是否匹配! 初始化: dp[0][0]:什么都没有,所以为true    第一行dp[0][j],换句话说,s为空,与p匹配,所以只要p开始为*才为true    第一列dp[i][0],当然全部为False 动态方程: 如果(s[i] == p[j] || p[j] == "?") && dp[i-1][

(Java) LeetCode 44. Wildcard Matching —— 通配符匹配

Given an input string (s) and a pattern (p), 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 enti

第八周 Leetcode 44. Wildcard Matching 水题 (HARD)

Leetcode 44 实现一种类似正则表达式的字符串匹配功能. 复杂度要求不高, 调代码稍微费点劲.. 好像跟贪心也不太沾边, 总之 *把待匹配串分成若干个子串, 每一个子串尽量在模式串中靠前的部分匹配完成就算贪心了吧.. class Solution { public: bool match(string &s,string &p,int l2,int r2,int l1) { if(l2==r2)return true; if(l1+r2-l2-1>=s.length())re

DP在字符匹配上的实现

在此保存下近段时间做的DP在字符匹配上的实现的题目 对于不同的字符串来说,2者只能不断将下标往后推移来实现匹配从而得到的最大匹配数 如 abcd 和 dcba 这个最大匹配数只能为1,因为两个d匹配后,在第一个字符串中是不能再拿前面的字符进行匹配的(当然你要是匹配a,b,c也是一样的道理) 对于每一道题目若想不断找到那个匹配成功的字符的话,我们需要一个函数不断递归找到前一个匹配成功的字符,这里引进一个T[N][N]的标志位来帮助我们判断何时进行递归 这里的题都是有关这个的形式 1.POJ 145

JavaScript正则表达式模式匹配(1)——基本字符匹配

1 var pattern=/g..gle/; //点符号表示匹配除了换行符外的任意字符 2 var str='g78gle'; 3 alert(pattern.test(str)); 4 5 6 var pattern=/go*gle/; //o* ,表示0个或者多个o 7 var str='goooooooooooogle'; 8 alert(pattern.test(str)); 9 10 var pattern=/go+gle/; //o+,表示一个或者多个o 11 var str='g

【编程题目】有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配...

37.(字符串)有 n 个长为 m+1 的字符串,如果某个字符串的最后 m 个字符与某个字符串的前 m 个字符匹配,则两个字符串可以联接,问这 n 个字符串最多可以连成一个多长的字符串,如果出现循环,则返回错误. 分析:如果出现循环,则返回错误 这句不懂 具体做法是先给每个字符串建一个vector 存入每个字符串后面可以匹配的字符串序号 然后遍历所有的搭配情况,找到最长的. 我的遍历代码很丑... 可谓又臭又长..... 深深的自我鄙视. /* 37.(字符串) 有 n 个长为 m+1 的字符串

将字符串s1中的任何与字符串s2中字符匹配的字符都删除

编写一个程序,将字符串s1中的任何与字符串s2中字符匹配的字符都删除. 函数原型:void my_squeeze(char s1[], char s2[]) #include <stdio.h> void my_squeeze(char s1[], char s2[]) { int i = 0; int j = 0; while (s2[j]) { while(s1[i]) { if (s2[j]==s1[i]) { while (s1[i+1]) { s1[i] = s1[i + 1]; i