代码随想录训练营算法第三十四天|动态规划|62.不同路径、63. 不同路径 II、343. 整数拆分、96.不同的二叉搜索树。

62.不同路径

 62. 不同路径 - 力扣(LeetCode)

代码随想录

        还是不太熟悉怎么递推,用dp[i][j]代表走到第i行j列有多少路线,而 i 行 j 列可以通过 [ i-1 ] [ j ] 和 [ i ][ j-1 ]分别走一步得到。

class Solution {
public:
    int uniquePaths(int m, int n) {
        vector> dp(m+1, vector(n+1, 0));
        for(int i = 1; i <= m; i++)  // 第一列初始化为1
            dp[i][1] = 1;
        for(int i = 1; i <= n; i++)  // 第一行初始化为1
            dp[1][i] = 1;
        for(int i = 2; i <= m; i++)
            for(int j = 2; j <= n; j++)
                dp[i][j] = dp[i-1][j] + dp[i][j-1]; // 递推公式
        return dp[m][n];
    }
};

63. 不同路径 II

 63. 不同路径 II - 力扣(LeetCode)

代码随想录

         有感觉了!第一眼看觉得好难,但是仔细一想发现跟上面一题是一个思路,唯一的不同点就是当遇到路障的时候dp[i][j]应该为0,表示不可达。并且注意初始化的过程中遇到路障就要break,剩下的递推公式就跟上一题一样了。

class Solution {
public:
    int uniquePathsWithObstacles(vector>& obstacleGrid) {
        int m = obstacleGrid.size();
        int n = obstacleGrid[0].size();
        vector> dp(m, vector(n, 0));
        
        for(int i = 0; i < m; i++){ // 初始化第一列
            if(obstacleGrid[i][0] == 0)
                dp[i][0] = 1;
            else    // 若是中途有路障,代表路障往下都不可达
                break;
        }
        for(int i = 0; i < n; i++){ // 初始化第一行
            if(obstacleGrid[0][i] == 0)
                dp[0][i] = 1;
            else    // 若是中途有路障,代表路障往右都不可达
                break;
        }

        for(int i = 1; i < m; i++){
            for(int j = 1; j < n; j++){
                if(obstacleGrid[i][j] == 1)
                    dp[i][j] = 0;   // 路障点不可达
                else{
                    dp[i][j] = dp[i-1][j] + dp[i][j-1]; // 递推公式
                }
            }
        }
        return dp[m-1][n-1];
    }
};

343. 整数拆分

 343. 整数拆分 - 力扣(LeetCode)

代码随想录

        没想到可以这样子来找最大值...还是经常想不出递推公式。

class Solution {
public:
    int integerBreak(int n) {
        vector dp(n+1, 0);
        dp[2] = 1;
        for(int i = 3; i <= n; i++){
            for(int j = 1; j <= i/2; j++){
                //j*(i-j) 拆分成两个数, j*dp[i-j]是拆分成两个或以上的数,这两者都有可能为最大值
                dp[i] = max(dp[i], max(j*dp[i-j], j*(i-j)));    
            }
        }
        return dp[n];
    }
};

96.不同的二叉搜索树

 96. 不同的二叉搜索树 - 力扣(LeetCode)

代码随想录

        有i个节点时,将i个节点分别当作根节点,如i = 3时,情况分别为:第一个结点当根:左子树0个节点,右子树2个节点;第二个节点当根:左子树1个节点,右子树1个节点;第三个节点当根:左子树2个节点,右子树0个节点。即可写出递推式。

class Solution {
public:
    int numTrees(int n) {
        vector dp(n+1); 
        dp[0] = 1; 
        dp[1] = 1;  // 无节点或一个节点均只有一种
        for(int i = 2; i <= n; i++){
            for(int j = 0; j < i; j++){
                dp[i] += dp[j] * dp[i-j-1]; // 共i种情况,每种情况左子树为j个,右子树为i-j-1个
            }
        }
        return dp[n];
    }
};

         有一点感觉了,再接再厉

你可能感兴趣的:(算法)