題目連接ide
題目大意:與62題相似,只是這個題中間有障礙。spa
法一:dfs,依舊超時。代碼以下:code
1 public int uniquePathsWithObstacles(int[][] obstacleGrid) { 2 boolean vis[][] = new boolean[obstacleGrid.length][obstacleGrid[0].length]; 3 int f[][] = {{1, 0}, {0, 1}}; 4 //若是起始格子就是障礙,則表示不能正常到達目的地 5 if(obstacleGrid[0][0] == 1) { 6 return 0; 7 } 8 return dfs(obstacleGrid, 0, 0, 0, f, vis); 9 } 10 public static int dfs(int[][] obstacleGrid, int x, int y, int cnt, int f[][], boolean vis[][]) { 11 if(x == obstacleGrid.length - 1 && y == obstacleGrid[0].length - 1 && obstacleGrid[x][y] == 0) { 12 cnt++; 13 return cnt; 14 } 15 for(int i = 0; i < 2; i++) { 16 int cnt_x = x + f[i][0]; 17 int cnt_y = y + f[i][1]; 18 if(cnt_x < obstacleGrid.length && cnt_y < obstacleGrid[0].length && vis[cnt_x][cnt_y] == false && obstacleGrid[cnt_x][cnt_y] == 0) { 19 vis[cnt_x][cnt_y] = true; 20 cnt = dfs(obstacleGrid, cnt_x, cnt_y, cnt, f, vis); 21 vis[cnt_x][cnt_y] = false; 22 } 23 } 24 return cnt; 25 }
法二:dp,模仿62題的dp,只是這裏要考慮障礙。代碼以下(耗時2ms):blog
1 public int uniquePathsWithObstacles(int[][] obstacleGrid) { 2 //若是起始位置或結束位置是1,則直接不通 3 if(obstacleGrid[0][0] == 1 || obstacleGrid[obstacleGrid.length - 1][obstacleGrid[0].length - 1] == 1) { 4 return 0; 5 } 6 int dp[][] = new int[obstacleGrid.length][obstacleGrid[0].length]; 7 //初始化第一列 8 for(int i = 0; i < obstacleGrid.length; i++) { 9 if(obstacleGrid[i][0] == 0) { 10 dp[i][0] = 1; 11 } 12 else {//第一列,一旦碰到一個障礙1,則第一列障礙下面的全部都是障礙,不通 13 for(; i < obstacleGrid.length; i++) { 14 dp[i][0] = 0; 15 } 16 break; 17 } 18 } 19 //初始化第一行 20 for(int i = 0; i < obstacleGrid[0].length; i++) { 21 if(obstacleGrid[0][i] == 0) { 22 dp[0][i] = 1; 23 } 24 else {//第一行,一旦碰到一個障礙1,則第一行障礙後面的全部都是障礙,不通 25 for(; i < obstacleGrid[0].length; i++) { 26 dp[0][i] = 0; 27 } 28 break; 29 } 30 } 31 //計算dp 32 for(int i = 1; i < obstacleGrid.length; i++) { 33 for(int j = 1; j < obstacleGrid[0].length; j++) { 34 if(obstacleGrid[i][j] == 1) {//若是當前格是障礙,則不可通 35 dp[i][j] = 0; 36 } 37 else { 38 dp[i][j] = dp[i - 1][j] + dp[i][j - 1]; 39 } 40 } 41 } 42 return dp[obstacleGrid.length - 1][obstacleGrid[0].length - 1]; 43 }
法三:一維dp,與62題很相似,可是要比62題難思考一點,由於要考慮障礙的問題,並且沒有初始化,直接從0開始遍歷的。代碼以下(耗時1ms):ip
1 public int uniquePathsWithObstacles(int[][] obstacleGrid) { 2 if(obstacleGrid[0][0] == 1 || obstacleGrid[obstacleGrid.length - 1][obstacleGrid[0].length - 1] == 1) { 3 return 0; 4 } 5 int[] dp = new int[obstacleGrid[0].length]; 6 dp[0] = 1; 7 //從0開始遍歷,不然會漏掉第一列,由於其實第一列並無初始化 8 for(int i = 0; i < obstacleGrid.length; i++) { 9 for(int j = 0; j < obstacleGrid[0].length; j++) { 10 //遇到障礙則賦0 11 if(obstacleGrid[i][j] == 1) { 12 dp[j] = 0; 13 } 14 //因爲j是從0開始,因此只考慮>0的狀況 15 else if(j > 0){ 16 dp[j] += dp[j - 1]; 17 } 18 } 19 } 20 return dp[obstacleGrid[0].length - 1]; 21 }