【算法】动态规划 LeetCode62、63

前言

LeetCode62、63属于动态规划类型的题目,其中63是62的加强版。所以,明白了62的思路,63就非常简单了。

问题描述

先看62问题描述

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
问总共有多少条不同的路径?

解题思路

从终点出发寻找规律,由于机器人只能向下或者向右,所以,分别计算终点上面那格路径总数和左边那格路径总数相加即可。

在这里插入图片描述

以此类推,从起点到达每一个格路径总数,可根据上面那格和左面那格路径总数相加即可。

代码

    public int uniquePaths(int m, int n) {
        int[][] dp = new int[m][n];
        for (int i=0;i<m;i++){
            for (int j=0;j<n;j++){
                if (i==0&&j==0){
                    // 如果只有一个格子,情况算1种,第一次提交失败就在这里
                    dp[i][j] = 1;
                }else if(i==0){
                    dp[i][j] = 1;
                }else if(j==0){
                    dp[i][j] = 1;
                }else {
                    dp[i][j] = dp[i-1][j] + dp[i][j-1];
                }
            }
        }
        return dp[m-1][n-1];
    }

增强版63题

此题目,是在62题目的基础上增加障碍物,如果遇到障碍物,词条路径就不能走了。假设终点上方有障碍物,那么count1=0,即上方路径总和为0。以此类推,如果某个上方或者左边有障碍物,那一个方向上路径总和为0就好。

在这里插入图片描述
特殊的,如果障碍物在第一行或者第一列上,障碍物后面或者下面的路径全都为0(毕竟机器人只能往下或者往右走嘛)
在这里插入图片描述

代码如下:

  public int uniquePathsWithObstacles(int[][] obstacleGrid) {
    // 起始位置就有障碍物的话
    if (obstacleGrid[0][0] == 1) {
      return 0;
    }
    int m = obstacleGrid.length;
    int n = obstacleGrid[0].length;
    // 横纵坐标是否有障碍物
    boolean xBarrier = false;
    boolean yBarrier = false;
    int[][] dp = new int[m][n];
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < n; j++) {
        if (i == 0) {
          if (obstacleGrid[i][j] == 1 && !xBarrier) {
            xBarrier = true;
          }
          if (xBarrier) {
            dp[i][j] = 0;
          } else {
            dp[i][j] = 1;
          }
        } else if (j == 0) {
          if (obstacleGrid[i][j] == 1 && !yBarrier) {
            yBarrier = true;
          }
          if (yBarrier) {
            dp[i][j] = 0;
          } else {
            dp[i][j] = 1;
          }
        } else {
          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];
  }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值