leetcode每日刷题计划--day61

Num 64 最小路径和

因为动态规划必考所以先刷一下动态规划tag

一遍过,题给vector是可变的,这边先用不可变的数组,稍微有点浪费可能?

然后从可能来的两个点找最小值加当前值即可。

一个可以优化的地方:1000*1000过大,实际上可以使用一维数组。(注意不要因为一维数组就省略了对i的判断,不然dp[j]的迭代更新会出错)

代码注释掉的是二维的,有的是一维的

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];
    }
};
View Code

 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]

第一道困难动态规划!夸我自己!

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];
    }
};
View Code
时间才能证明一切,选好了就尽力去做吧!
原文地址:https://www.cnblogs.com/tingxilin/p/11959461.html