1. 程式人生 > >leetcode刷題之旅(63)不同路徑II

leetcode刷題之旅(63)不同路徑II

題目描述

一個機器人位於一個 m x n 網格的左上角 (起始點在下圖中標記為“Start” )。

機器人每次只能向下或者向右移動一步。機器人試圖達到網格的右下角(在下圖中標記為“Finish”)。

現在考慮網格中有障礙物。那麼從左上角到右下角將會有多少條不同的路徑?

網格中的障礙物和空位置分別用 1 和 0 來表示。

說明:m 和 的值均不超過 100。

樣例

輸入:
[
  [0,0,0],
  [0,1,0],
  [0,0,0]
]
輸出: 2
解釋:
3x3 網格的正中間有一個障礙物。
從左上角到右下角一共有 2 條不同的路徑:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右

思路分析

和上題思路一致,不過數學方法不可取了

有障礙物的情況,即到此處的路徑計數歸零

程式碼及結果

方法一:

public static int uniquePathsWithObstacles(int[][] obstacleGrid) {
		int m = obstacleGrid.length;
		int n = obstacleGrid[0].length;
		if (m<0 || n<0 || m>100 || n>100) {
			return 0;
		}
		int dp[][] = new int[m][n];
		if (obstacleGrid[0][0] == 1) {
			return 0;
		}
		dp[0][0] = 1;
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				if (obstacleGrid[i][j] == 1) {
					dp[i][j] = 0;
				}
				else if (i==0) {
					if(j>0) dp[i][j] = dp[i][j-1];
				}
				else if (j==0) {
					if(i>0) dp[i][j] = dp[i-1][j];
				}
				else {
					dp[i][j] = dp[i-1][j] + dp[i][j-1];
				}
			}
		}
		return dp[m-1][n-1];
    }

方法二:

public static int uniquePathsWithObstacles(int[][] obstacleGrid) {
		int m = obstacleGrid.length;
		int n = obstacleGrid[0].length;
		if (m<0 || n<0 || m>100 || n>100) {
			return 0;
		}
		int dp[] = new int[n];
		if (obstacleGrid[0][0] == 1) {
			return 0;
		}
		dp[0] = 1;
		for (int i = 0; i < m; i++) {
			for (int j = 0; j < n; j++) {
				if (obstacleGrid[i][j] == 1){
					dp[j] = 0;
				}
				else if (j > 0) {
					dp[j] = dp[j] + dp[j-1];
				}
			}
		}
		return dp[n-1];
	}