演算法——路徑問題

IT_Painter發表於2020-10-04

路徑總數

題目描述:

  在一個m*n的網格的左上角有一個機器人,機器人在任何時候只能向下或者向右移動,機器人試圖到達網格的右下角,有多少可能的路徑。

來源:牛客連結

思路:動態規劃

F(i,j) = F(i-1,j) + F(i,j-1)
特殊情況:第0行和第0列
 F(0,i) = 1
 F(i,0) = 1

程式碼:

import java.util.*;

public class Solution {
    /**
     * @param m int整型
     * @param n int整型
     * @return int整型
     */
    public int uniquePaths(int m, int n) {
        // write code here
        List<List<Integer>> pathNum = new ArrayList<>();
        // 申請F(i,j)空間,初始化
        for (int i = 0; i < m; ++i) {
            pathNum.add(new ArrayList<>());
            pathNum.get(i).add(1);
        }
        for (int i = 1; i < n; ++i) {
            pathNum.get(0).add(1);
        }
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                // F(i,j) = F(i-1,j) + F(i,j-1)
                pathNum.get(i).add(pathNum.get(i).get(j - 1) + pathNum.get(i - 1).get(j));
            }
        }
        return pathNum.get(m - 1).get(n - 1);
    }
}

路徑總數(有障礙物)

題目描述:

繼續求路徑。
如果在圖中加入了一些障礙,有多少不同的路徑?
分別用0和1代表空區域和障礙

來源:牛客連結

思路:動態規劃

F(i,j) = {F(i-1,j) + F(i,j-1)} OR {0, if obstacleGrid(i,j) = 1}
特殊情況:第0行和第0列
  F(0,i) = {1} OR {0, if obstacleGrid(0,j) = 1, j <= i}
  F(i,0) = {1} OR {0, if obstacleGrid(j,0) = 1, j <= i}

程式碼:

package java_1004;

import java.util.*;


public class Solution {
    /**
     *
     * @param obstacleGrid int整型二維陣列
     * @return int整型
     */
    public int uniquePathsWithObstacles (int[][] obstacleGrid) {
        // write code here
        if(obstacleGrid==null)return 0;
        List<List<Integer>> pathNum = new ArrayList<>();
        int m = obstacleGrid.length;
        int n = obstacleGrid[0].length;
        // 申請F(i,j)空間,初始化
        // 初始化第0列
        for (int i = 0; i < m; ++i) {
            pathNum.add(new ArrayList<>());
            //如果當前位置有障礙,則無法到達
            if (obstacleGrid[i][0] == 1)
                pathNum.get(i).add(0);
            else {
                //如果當前位置無障礙,但是前面如果到達不了,當前位置也達到不了
                if (i > 0) {
                    if (pathNum.get(i - 1).get(0) == 1)
                        pathNum.get(i).add(1);
                    else
                        pathNum.get(i).add(0);
                } else
                    pathNum.get(i).add(1);
            }
        }
        //初始化第一行
        for (int i = 1; i < n; ++i) {
            if (obstacleGrid[0][i] == 1)
                pathNum.get(0).add(0);
            else {
                if (pathNum.get(0).get(i - 1) == 1)
                    pathNum.get(0).add(1);
                else
                    pathNum.get(0).add(0);
            }
        }
        for (int i = 1; i < m; ++i) {
            for (int j = 1; j < n; ++j) {
                // obstacleGrid[i][j] = 1 時,F(i,j)無法到達
                if (obstacleGrid[i][j] == 1)
                    pathNum.get(i).add(0);
                else
                    // F(i,j) = F(i-1,j) + F(i,j-1)
                    pathNum.get(i).add(pathNum.get(i).get(j - 1)
                            + pathNum.get(i - 1).get(j));
            }
        }
        return pathNum.get(m - 1).get(n - 1);
    }
}

最小路徑和(左上角到右下角)

題目描述

給定一個由非負整數填充的m x n的二維陣列,現在要從二維陣列的左上角走到右下角,請找出路徑上的所有數字之和最小的路徑。
注意:你每次只能向下或向右移動。

來源:牛客連結

思路:動態規劃

F(i,j) = min{F(i-1,j) , F(i,j-1)} + F(i,j)
特殊情況:第0行和第0列
  F(0,i) = F(0,i-1) + (0,i)
  F(i,0) = F(i-1,0) + (i,0)

程式碼:

import java.util.*;


public class Solution {
    /**
     * 
     * @param grid int整型二維陣列 
     * @return int整型
     */
    public int minPathSum (int[][] grid) {
        // write code here
        int row = grid.length;
        int col = grid[0].length;
        // 如果為空或者只有一行,返回0
        if(row == 0 || col == 0) {
            return 0;
         }
         // F(0,0), F(0,i), F(i,0)初始化
        for(int i = 1;i < row;i++) {
            grid[i][0] = grid[i - 1][0] + grid[i][0];
        }
        for(int i = 1;i < col;i++) {
            grid[0][i] = grid[0][i - 1] + grid[0][i];
        }
        // F(i,j) = min{F(i-1,j) , F(i,j-1)} + F(i,j)
        for(int i=1;i < row;i++){
            for(int j = 1;j < col;j++) {
                grid[i][j] = Math.min(grid[i - 1][j],grid[i][j - 1]) + grid[i][j];
            }
        }
        return grid[row-1][col-1];
    }
}

相關文章