问题1:leetcode 正则表达式匹配

请实现一个函数用来匹配包括'.'和'*'的正则表达式。模式中的字符'.'表示任意一个字符,而'*'表示它前面的字符可以出现任意次(包含0次)。 在本题中,匹配是指字符串的所有字符匹配整个模式。例如,字符串"aaa"与模式"a.a"和"ab*ac*a"匹配,但是与"aa.a"和"ab*a"均不匹配

思路:

如果 pattern[j] == str[i] || pattern[j] == '.', 此时dp[i][j] = dp[i-1][j-1];

如果 pattern[j] == '*'
    分两种情况:
    1: 如果pattern[j-1] != str[i] && pattern[j-1] != '.',
此时dp[i][j] = dp[i][j-2] //a*匹配0次
    2: 如果pattern[j-1] == str[i] || pattern[j-1] == '.'
        此时dp[i][j] = dp[i][j-2] // a*匹配0次
        或者 dp[i][j] = dp[i][j-1] // a*匹配1次
        或者 dp[i][j] = dp[i-1][j] // a*匹配多次
 public boolean match(char[] str, char[] pattern)
{
 if(str == null || pattern == null)  return true;boolean [][] dp = new boolean[str.length+1][pattern.length+1];
dp[0][0] = true;
for(int i=1; i<dp[0].length;i++){
if(pattern[i-1] == '*'){
dp[0][i] = dp[0][i-2];
}
}
for(int i=1; i<dp.length; i++){
for(int j=1;j<dp[0].length; j++){
if(pattern[j-1] == '*'){
if(str[i-1] == pattern[j-2] || pattern[j-2] == '.'){
dp[i][j] = dp[i][j-2] || dp[i-1][j] || dp[i][j-1];
// 0 多次 一次
}
else{
dp[i][j] = dp[i][j-2];
}
}
else if(str[i-1] == pattern[j-1] || pattern[j-1] == '.'){
dp[i][j] = dp[i-1][j-1];
}
}
} for(int i=0; i<dp.length; i++){
for(int j=0; j<dp[0].length; j++){
System.out.print(dp[i][j] + " ");
}
System.out.println();
}
return dp[dp.length-1][dp[0].length-1];
}

问题2:  leetcode 44 通配符匹配

给定一个字符串 (s) 和一个字符模式 (p) ,实现一个支持 '?' 和 '*' 的通配符匹配。

'?' 可以匹配任何单个字符。
'*' 可以匹配任意字符串(包括空字符串)。

两个字符串完全匹配才算匹配成功。

思路: 定义dp[i][j]为s的前i个字符与p的前j个字符是否匹配,那么当p[j] 为‘*’的时候, dp[i][j] = dp[i][j-1] || (i >0 && (dp[i-1][j] || dp[i-1][j-1]) );// 匹配多次或者一次

当p[j-1]为“?”时候,dp[i][j] = dp[i-1][j-1]

class Solution {
public boolean isMatch(String s, String p) {
int m = s.length(), n=p.length();
boolean[][] dp = new boolean[m+1][n+1];
dp[0][0] = true;
// String str = "adceb";
// String pattern = "*a*b";
for(int i = 0; i<=m; i++){
for(int j=1;j<=n;j++){
if( p.charAt(j-1)=='*'){
dp[i][j] = dp[i][j-1] || (i >0 && (dp[i-1][j] || dp[i-1][j-1]) );// 匹配多次或者一次
}
if( i>=1 && (p.charAt(j-1)=='?' || s.charAt(i-1) == p.charAt(j-1)) ){
dp[i][j] = dp[i-1][j-1];
}
}
} // for(int i = 0; i<=m; i++){
// for(int j=0;j<=n;j++) {
// System.out.print(dp[i][j] + " ");
// }
// System.out.println();
// }
return dp[m][n];
}
}

问题三:leetcode 97 交替字符串

给定三个字符串 s1, s2, s3, 验证 s3 是否是由 s1 和 s2 交错组成的。

示例 1:

输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"
输出: true

示例 2:

输入: s1 = "aabcc", s2 = "dbbca", s3 = "aadbbbaccc"
输出: false 思路: 定义dp[i][j]为s1的前i个字符与s2的前j个字符是否可以组成s3的前i+j个字符,注意空字符串,所以s1与s2都是从1开始计数的
class Solution {
public boolean isInterleave(String s1, String s2, String s3) {
if(s1.equals("")){
return s2.equals(s3);
}
if(s2.equals("")){
return s1.equals(s3);
} int m = s1.length(), n = s2.length();
if(m+n != s3.length()){
return false;
}
boolean[][] dp = new boolean[m+1][n+1];
dp[0][0] = true; // String s1 = "aabcc", s2 = "dbbca", s3 = "aadbbcbcac"; for(int i=0; i<= m; i++){
for(int j=0; j<=n;j++){
if(i==0 && j==0) continue;
dp[i][j] = (i>0 && s1.charAt(i-1)==s3.charAt(i+j-1) && dp[i-1][j]) ||
(j>0 && s2.charAt(j-1) == s3.charAt(i+j-1) && dp[i][j-1] );
}
} // for(int i=0; i<= m; i++){
// for(int j=0; j<=n;j++) {
// System.out.print(dp[i][j] +" ");
// }
// System.out.println();
// }
return dp[m][n];
}
}

leetcode 不同子序列 115

给定一个字符串 和一个字符串 T,计算在 S 的子序列中 T 出现的个数。

一个字符串的一个子序列是指,通过删除一些(也可以不删除)字符且不干扰剩余字符相对位置所组成的新字符串。(例如,"ACE" 是 "ABCDE" 的一个子序列,而 "AEC" 不是)

示例 1:

输入: S = "rabbbit", T = "rabbit"
输出: 3
解释:

如下图所示, 有 3 种可以从 S 中得到 "rabbit" 的方案
(上箭头符号 ^ 表示选取的字母) rabbbit
^^^^ ^^
rabbbit
^^ ^^^^
rabbbit
^^^ ^^^

示例 2:

输入: S = "babgbag", T = "bag"
输出: 5
解释:

如下图所示, 有 5 种可以从 S 中得到 "bag" 的方案
(上箭头符号 ^ 表示选取的字母) babgbag
^^ ^
babgbag
^^ ^
babgbag
^ ^^
babgbag
^ ^^
babgbag

思路1: 定义 dp[i][j] 为s[i]等于t[j]的子序列数目:dp[i][j] += dp[k][j-1]; s[k] = t[j-1];

class Solution {
public int numDistinct(String s, String t) {
// S = "rabbbit", T = "rabbit" // String S = "babgbag", T = "bag";
int m = s.length(), n = t.length();
int[][] dp = new int[m][n];
// dp[i][j] = dp[k][j-1] s[k] == t[j]
for(int i=0; i<m;i++){
dp[i][0] = s.charAt(i) == t.charAt(0) ? 1 : 0;
}
for(int i=0; i<m;i++){
for(int j=0; j<n;j++){
if(s.charAt(i) == t.charAt(j)) {
for (int k = 0; k < i; k++) {
if (j>0 && s.charAt(k) == t.charAt(j-1)) {
dp[i][j] += dp[k][j-1];
}
}
}
}
}
// for(int i=0; i<m;i++) {
// for (int j = 0; j < n; j++) {
// System.out.print(dp[i][j]+" ");
// }
// System.out.println();
// }
int result = 0;
for(int i=0 ; i<m;i++){
result += dp[i][n-1];
}
return result;
}
}

思路2:

而是判断S有多少种方式可以得到T。但其实还是动态规划,我们一个定义二维数组dp,dp[i][j]为字符串s(0,i)变换到t(0,j)的变换方法的个数。

如果S[i]==T[j],那么dp[i][j] = dp[i-1][j-1] + dp[i-1][j]。意思是:如果当前S[i]==T[j],那么当前这个字符即可以保留也可以抛弃,所以变换方法等于保留这个字符的变换方法加上不用这个字符的变换方法, dp[i-1][j-1]为保留这个字符时的变换方法个数,dp[i-1][j]表示抛弃这个字符时的变换方法个数。
如果S[i]!=T[i],那么dp[i][j] = dp[i-1][j],意思是如果当前字符不等,那么就只能抛弃当前这个字符。

class Solution {
public int numDistinct(String s, String t) {
int[][] res = new int[s.length()+1][t.length()+1];
res[0][0] = 1;
for(int i=1;i<t.length()+1;i++)
res[0][i] = 0;
for(int i=1;i<s.length()+1;i++)
res[i][0] = 1;
for(int i=1;i<s.length()+1;i++)
for(int j=1;j<t.length()+1;j++){
if(s.charAt(i-1)==t.charAt(j-1)){
res[i][j] = res[i-1][j-1] + res[i-1][j];
}
else{
res[i][j] = res[i-1][j];
}
}
return res[s.length()][t.length()];
}
}

leetcode 字符串动态规划总结的更多相关文章

  1. Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings)

    Leetcode之动态规划(DP)专题-712. 两个字符串的最小ASCII删除和(Minimum ASCII Delete Sum for Two Strings) 给定两个字符串s1, s2,找到 ...

  2. leetcode笔记 动态规划在字符串匹配中的应用

    目录 leetcode笔记 动态规划在字符串匹配中的应用 0 参考文献 1. [10. Regular Expression Matching] 1.1 题目 1.2 思路 && 解题 ...

  3. Leetcode之动态规划(DP)专题-647. 回文子串(Palindromic Substrings)

    Leetcode之动态规划(DP)专题-647. 回文子串(Palindromic Substrings) 给定一个字符串,你的任务是计算这个字符串中有多少个回文子串. 具有不同开始位置或结束位置的子 ...

  4. Leetcode之动态规划(DP)专题-474. 一和零(Ones and Zeroes)

    Leetcode之动态规划(DP)专题-474. 一和零(Ones and Zeroes) 在计算机界中,我们总是追求用有限的资源获取最大的收益. 现在,假设你分别支配着 m 个 0 和 n 个 1. ...

  5. Leetcode之动态规划(DP)专题-392. 判断子序列(Is Subsequence)

    Leetcode之动态规划(DP)专题-392. 判断子序列(Is Subsequence) 给定字符串 s 和 t ,判断 s 是否为 t 的子序列. 你可以认为 s 和 t 中仅包含英文小写字母. ...

  6. Leetcode之动态规划(DP)专题-72. 编辑距离(Edit Distance)

    Leetcode之动态规划(DP)专题-72. 编辑距离(Edit Distance) 给定两个单词 word1 和 word2,计算出将 word1 转换成 word2 所使用的最少操作数 . 你可 ...

  7. LeetCode 字符串专题(一)

    目录 LeetCode 字符串专题 <c++> \([5]\) Longest Palindromic Substring \([28]\) Implement strStr() [\(4 ...

  8. 【leetcode 字符串处理】Compare Version Numbers

    [leetcode 字符串处理]Compare Version Numbers @author:wepon @blog:http://blog.csdn.net/u012162613 1.题目 Com ...

  9. Leetcode之动态规划(DP)专题-详解983. 最低票价(Minimum Cost For Tickets)

    Leetcode之动态规划(DP)专题-983. 最低票价(Minimum Cost For Tickets) 在一个火车旅行很受欢迎的国度,你提前一年计划了一些火车旅行.在接下来的一年里,你要旅行的 ...

随机推荐

  1. Atcoder 2373 Cookie Exchanges

    Problem Statement Takahashi, Aoki and Snuke love cookies. They have A, B and C cookies, respectively ...

  2. 数据库设计三范式(3NF)

    问:当时你数据库是如何设计的? 答:当时是按照三范式规范设计的: 第一范式: 1:数据库的原子性,即保证数据库表的每一列都不可分割的 第二范式: 1:原子性,即保证数据库表的每一列都不可分割 2:表中 ...

  3. Android-事件体系全面总结+实践分析

    事件分发在Android中是很重要的基础知识,网上相关的文章也很多,但是花了很多精力看了很多别人的分析总结,最终的感觉还是似懂非懂,所以决定自己动手研究一下,去发现其中的规律.本文顺着我自己的思路去研 ...

  4. 【mac】mac上安装软件,报错 鉴定错误,但是安装包都是好的

    出现这个问题, 原因解析: 不是你的安装包下载出错了或者下载失败了这种原因 而是你在打开这个安装包的时候,一定是让你输入密码,而你的密码没有输入正确 解决方式:重新开始打开这个软件的安装包 如下: 1 ...

  5. java之 ------ 文件的输入、输出(一)

    import java.io.*; public class IntFile { private String filename; public IntFile(String filename) { ...

  6. A002-开发工具介绍

    关于Android的开发工具有非常多,基本上都能够在SDK中找到.下面我们逐个来看一下: 首先我们使用的是Java语言进行Android应用的开发,那么Java的执行环境是少不了的了,我们须要在我们的 ...

  7. three.js 源代码凝视(九)Math/Matrix4.js

    商域无疆 (http://blog.csdn.net/omni360/) 本文遵循"署名-非商业用途-保持一致"创作公用协议 转载请保留此句:商域无疆 -  本博客专注于 敏捷开发 ...

  8. Servlet的部署开发细节以及注意事项

    学习servlet最困难的我感觉还是配置,一開始是非常麻烦的.为了较好的学习,一開始还是以手动开发我认为比較好,可是真的有点把握给搞晕了,尤其是部署servlet方面非常麻烦,这里做一下简单的总结,前 ...

  9. YII 多子域名同步登录

    a.meylou.com和b.meylou.com不做登录.c.meylou.com这个专门做用户登录.c站登录之后a,b站点同时登录. 第一步:修改php.ini配置文件,把cookie_domai ...

  10. Atlassian Confluence安装

    前言 Confluence与Jira 由于线上jira和confluence之前互相关联,confluence的登录用户全部关联自jira的用户,confluence安装时会提示是否关联jira,由于 ...