Num 64 最小路径和
因为动态规划必考所以先刷一下动态规划tag
一遍过,题给vector是可变的,这边先用不可变的数组,稍微有点浪费可能?
然后从可能来的两个点找最小值加当前值即可。
一个可以优化的地方:1000*1000过大,实际上可以使用一维数组。(注意不要因为一维数组就省略了对i的判断,不然dp[j]的迭代更新会出错)
代码注释掉的是二维的,有的是一维的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution { public: int minPathSum(vector<vector<int>>& grid) { int x=grid.size(); int y=grid[0].size(); //int dp[1000][1000]; int dp[1000]; memset(dp,0,sizeof(dp)); dp[0]=grid[0][0]; /*for(int i=0;i<x;i++) { for(int j=0;j<y;j++) { if(j>=1 && i>=1) dp[i][j]=min(dp[i-1][j],dp[i][j-1])+grid[i][j]; else if(j>=1) dp[i][j]=dp[i][j-1]+grid[i][j]; else if(i>=1) dp[i][j]=dp[i-1][j]+grid[i][j]; } }*/ for(int i=0;i<x;i++) { for(int j=0;j<y;j++) { if(j>=1 && i>=1) dp[j]=min(dp[j],dp[j-1])+grid[i][j]; else if(j>=1) dp[j]=dp[j-1]+grid[i][j]; else if(i>=1) dp[j]=dp[j]+grid[i][j]; } } return dp[y-1]; } };
Num 10 正则表达式匹配
动态规划 hard 卡住了一下 参考了一下题解
dp[i][j]的定义作用是,s的前i个和p的前j个,是否能够顺利匹配
注意要点:
1、初始化的时候,因为dp[n][0]是肯定不可能为真的,所以用默认false就行不用再赋值
2、边界条件非常重要,dp[0][n]是真,只有可能都是x*这种格式,如果是x*,那么需要dp[0][n-2]
3、理解题目,.是可以匹配任意字符,但是不能是空,因此dp[0][1]一定为假,因此dp[0][奇数]一定是假的
4、转移方程在x*且x能与p[倒数第二个匹配的情况下比较困难。
这里面对应了如下的几种模式
1)如果s尾与p倒数第二配,那么多了一个*仍可匹配(*在前面取完以后此处不取) dp[i][j]=dp[i][j-1]
2)如果s尾与p倒三配,那么x*空,可匹配。 dp[i][j]=dp[i][j-2]
3)如果s倒二与p尾配,那么*在匹配字符串基础上取一个x,dp[i][j]=dp[i-1][j]
4)如果s倒二与p倒二配,那么*在匹配字符串基础上取一个x,dp[i][j]=dp[i-1][j-1](注意这个和上面字面同,但是要s倒二与尾配,相同串肯定是取得更多x的,我们现在假设已有匹配串了,只考虑在他的基础上取什么)
//5)如果s倒二与p倒三配,那么x*合计取x dp[i][j]=dp[i-1][j-2]
ps:后期修改,5是没有实际意义的一句,如果符合5,必定符合1,可以去掉这句话。
重新再看这道题的理解方式:
1、*与s[i-1]是匹配的,两种,一种是*第一次作用dp[i-1][j-1],另一种是作用了大于一次dp[i-1][j]
2、*实际上不占用匹配位置(即x*整体为空或者为x),为空对应的是dp[i][j-2],为x对应的是dp[i][j-1]
第一道困难动态规划!夸我自己!
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
class Solution { public: bool isMatch(string s, string p) { int lens=s.length(); int lenp=p.length(); if(p=="") { if(s=="") return true; return false; } bool dp[300][300]; memset(dp,0,sizeof(dp)); dp[0][0]=true; if(s[0]==p[0]||p[0]=='.') dp[1][1]=true; //if(p[0]=='.') dp[0][1]=true; for(int j=2;j<=lenp;j++) dp[0][j]=dp[0][j-2] && p[j-1]=='*'; for(int i=1;i<=lens;i++) { for(int j=2;j<=lenp;j++) { if(s[i-1]==p[j-1]||p[j-1]=='.') { dp[i][j]=dp[i-1][j-1]; } else if(p[j-1]=='*') { if(p[j-2]==s[i-1]||p[j-2]=='.') { dp[i][j]=dp[i][j-1]||dp[i][j-2]||dp[i-1][j-1]||dp[i-1][j]; }//dp[i-1][j-2]这个不需要 else { dp[i][j]=dp[i][j-2]; } } } } return dp[lens][lenp]; } };