力扣算法学习day27-2

文章目录

  • 力扣算法学习day27-2
    • 62-不同路径
      • 题目
      • 代码实现
    • 63-不同路径 II
      • 题目
      • 代码实现
    • 343-整数拆分
      • 题目
      • 代码实现

力扣算法学习day27-2

62-不同路径

题目

力扣算法学习day27-2_第1张图片

力扣算法学习day27-2_第2张图片

代码实现

class Solution {
    public int uniquePaths(int m, int n) {
        // dp:题中很明显的提示在于机器人只能向右或向下移动,所以可以得到:
        // 1.第一排只有一种情况到达,即从它左边向右到达。2.第一列同理,也只有一种。
        // 然后,非第一排、第一列的情况,一定是由上面向下得到,左边向右得到,故迭代公式也就出来了。

        // 1.创建dp数组
        int[][] dp = new int[m][n];

        // 2.迭代公式:i>0,j>0时,dp[i][j] = dp[i][j-1] + dp[i-1][j]
        // 3.初始化dp数组
        for(int i = 0;i < dp[0].length;i++){
            dp[0][i] = 1;
        }
        for(int i = 0;i < dp.length;i++){
            dp[i][0] = 1;
        }

        // 4.确定遍历顺序,从公式接合图形很容得到应该一排一排的计算。
        for(int i = 1;i < dp.length;i++){
            for(int j = 1;j < dp[i].length;j++){
                dp[i][j] = dp[i][j-1] + dp[i-1][j];
            }
        }

        // 5.打印dp数组看是否与预期相符。
        // for(int i = 0;i < dp.length;i++){
        //     for(int j = 0;j < dp[i].length;j++){
        //         System.out.print(dp[i][j]+"\t");
        //     }
        //     System.out.println();
        // }

        return dp[m-1][n-1];
    }
}

63-不同路径 II

题目

力扣算法学习day27-2_第3张图片

力扣算法学习day27-2_第4张图片

代码实现

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        // dp
        // 1.创建dp数组
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        int[][] dp = new int[m][n];
        
        // 2.迭代公式,和上面那道题一样。原理也一样,只是遇到障碍物需要处理罢了。
        // dp[i][j] = dp[i][j-1] + dp[i-1][j]
        // 3.初始化dp数组
        for(int i = 0;i < n;i++){
            if(obstacleGrid[0][i] == 1){
                break;// 后面全部置0,因为初始化这里只有这一条路径到达。
            }
            dp[0][i] = 1;
        }
        for(int i = 0;i < m;i++){
            if(obstacleGrid[i][0] == 1){
                break;
            }
            dp[i][0] = 1;
        }

        // 4.确定遍历顺序,和上面那道一样,只是需要判断是否遇到障碍物。
        for(int i = 1;i < m;i++){
            for(int j = 1;j < n;j++){
                if(obstacleGrid[i][j] == 1){
                    continue;
                }
                dp[i][j] = dp[i][j-1] + dp[i-1][j];
            }
        }

        // 5.检查
        // for(int i = 0;i < m;i++){
        //     for(int j = 0;j < n;j++){
        //         System.out.print(dp[i][j] + "\t");
        //     }
        //     System.out.println();
        // }

        return dp[m-1][n-1];
    }
}

343-整数拆分

题目

力扣算法学习day27-2_第5张图片

代码实现

class Solution {
    public int integerBreak(int n) {
        // dp
        // 1.创建dp数组,确定下标的含义,dp[i] 表示i拆分后的最大乘积。
        int[] dp = new int[n+1];

        // 2.确定递归公式:主要思考是化多分为固定的两分。
        // 理论:首先,每个数的和(该数应该大于2才有意义)可以拆分成两种情况:
        // (1) j * dp[i-j] , j从1开始,到j = i-2结束。
        // (2) j * (i-j) , 这种情况是(1)没有包括的情况,需要单独计算。
        // (1)中没有包含的j=i-1的情况是j * dp[i-j] -> (i-1) * dp[1],1不可拆分,所以就等于(i-1) * 1,
        // 实际上这种情况包含在了(2)中了,那么在比较中就会覆盖到,而dp[i-j]不取1,0是因为它们不可拆分。
        // 最后,可以得出:dp[i](一轮) = Math.max(j * (i-j),j * dp[i-j]),但这只是每一轮比较的最大值所以
        // 需要将j遍历到j=i-2,每次比较更新最大值,故真正的迭代公式为:
        // dp[i] = Math.max(dp[i],Math.max(j * (i-j),j * dp[i-j]))
        // 3.初始化dp数组
        dp[2] = 1;
        
        // 4.确定遍历顺序dp数组0,1没有意义,2是初始化,所以从3开始。
        for(int i = 3;i < dp.length;i++){
            for(int j = 1;j < i-1;j++){// (1)中已经说了,j最大为i-2
                dp[i] = Math.max(dp[i],Math.max(j * (i-j),j * dp[i-j]));
            }
        }

        // 5.检查结果
        // for(int i = 0;i < dp.length;i++){
        //     System.out.print(dp[i]);
        // }

        return dp[n];
    }
}

你可能感兴趣的:(算法刷题,算法,leetcode,动态规划)