[Leetcode学习-java]Unique Paths I ~ III

This type of problem is a simple usage of DP:

Related algorithms:

P1002-crossing the river: https://blog.csdn.net/qq_28033719/article/details/106261183


Unique Paths I

problem:

Difficulty: easy

Article link: https://blog.csdn.net/qq_28033719/article/details/107033638


Unique Paths II

problem:

Difficulty: medium

Description:

Enter a two-dimensional array int[][], the robot will only go right and left, and then there are more rocks, the robot cannot pass through the rocks, 0 means no rocks, 1 means there are rocks.

Subject link: https://leetcode.com/problems/unique-paths-ii/

Enter the case:

Input: obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
Output: 2
Explanation: There is one obstacle in the middle of the 3x3 grid above.
There are two ways to reach the bottom-right corner:
1. Right -> Right -> Down -> Down
2. Down -> Down -> Right -> Right

My code:

In fact, it is also the same as the river crossing pawn. The river crossing pawn is a horse at any rate. It is just a stone and simpler.

Two-dimensional array approach:

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int x = obstacleGrid.length;
        int y = obstacleGrid[0].length;
        int[][] dp = new int[x][y];
        for(int i = 0;i < x;i ++) 
            if(obstacleGrid[i][0] != 1) dp[i][0] = 1;
            else break;
        for(int i = 0;i < y;i ++) 
            if(obstacleGrid[0][i] != 1) dp[0][i] = 1;
            else break;
        
        for(int i = 1;i < x;i ++) 
            for(int j = 1;j < y;j ++) 
                if(obstacleGrid[i][j] != 1) dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
        return dp[x - 1][y - 1];
    }
}

Changing to a one-dimensional array actually reduces space complexity:

class Solution {
    public int uniquePathsWithObstacles(int[][] obstacleGrid) {
        int x = obstacleGrid.length;
        int y = obstacleGrid[0].length;
        int[] dp = new int[y];
        for(int i = 0;i < y;i ++) 
            if(obstacleGrid[0][i] != 1) dp[i] = 1;
            else break;
        
        boolean open = obstacleGrid[0][0] != 1; // 做 X 轴石头标记
        for(int i = 1;i < x;i ++) {
            if(open) dp[0] = (open = obstacleGrid[i][0] != 1) ? 1 : 0;
            for(int j = 1;j < y;j ++)
                dp[j] = obstacleGrid[i][j] != 1 ? dp[j] + dp[j - 1] : 0;
        }
        return dp[y - 1];
    }
}

You can also use the array given by the input to distinguish between the two numbers of the stone path, especially the numbers at the beginning and the beginning of the boundary.

class Solution {
    public int uniquePathsWithObstacles(int[][] ob) {
        int x = ob.length;
        int y = ob[0].length;
        boolean block = ob[0][0] == 1; // 要区分开头是否阻塞了
        for(int i = 0;i < x;i ++)
            if(ob[i][0] != 1) ob[i][0] = 1;
            else
                for(;i < x;i ++) ob[i][0] = 0; // 注意边界的阻塞是全部
        for(int i = 1;i < y;i ++)
            if(!block && ob[0][i] != 1) ob[0][i] = 1;
            else
                for(;i < y;i ++) ob[0][i] = 0; // 注意边界的阻塞是全部

        for(int i = 1;i < x;i ++)
            for(int j = 1;j < y;j ++)
                ob[i][j] = ob[i][j] != 1 ? ob[i - 1][j] + ob[i][j - 1] : 0;
        return ob[x - 1][y - 1];
    }
}

 


Unique Paths III

problem:

Difficulty: hard

Description:

Enter a two-dimensional array int[][], the robot can move up, down, left, and right, then -1 means it can’t walk, 1 means the start position, 2 means the end position, the robot has to go to the place where the map is 0, how many ways to return .

Subject link: https://leetcode.com/problems/unique-paths-iii/

Input range:

 

  1. 1 <= grid.length * grid[0].length <= 20

 

Enter the case:

Example 1:
Input: [[1,0,0,0],[0,0,0,0],[0,0,2,-1]]
Output: 2
Explanation: We have the following two paths: 
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2)
2. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2)

Example 2:
Input: [[1,0,0,0],[0,0,0,0],[0,0,0,2]]
Output: 4
Explanation: We have the following four paths: 
1. (0,0),(0,1),(0,2),(0,3),(1,3),(1,2),(1,1),(1,0),(2,0),(2,1),(2,2),(2,3)
2. (0,0),(0,1),(1,1),(1,0),(2,0),(2,1),(2,2),(1,2),(0,2),(0,3),(1,3),(2,3)
3. (0,0),(1,0),(2,0),(2,1),(2,2),(1,2),(1,1),(0,1),(0,2),(0,3),(1,3),(2,3)
4. (0,0),(1,0),(2,0),(2,1),(1,1),(0,1),(0,2),(0,3),(1,3),(1,2),(2,2),(2,3)

Example 3:
Input: [[0,1],[2,0]]
Output: 0
Explanation: 
There is no path that walks over every empty square exactly once.
Note that the starting and ending square can be anywhere in the grid.

My code:

In this case, I looked at the topic for a long time, and it turned out that I had to go through all 0s. No wonder the result analysis is so complicated.

Specifically, dp is just a dfs approach. Fortunately, the input area is less than 20, so it will not be too time-consuming.

class Solution {
    private static int x = 0;
    private static int y = 0;
    private static int count = 0;
    
    public int uniquePathsIII(int[][] grid) {
        count = 1;
        x = grid.length;
        y = grid[0].length;
        int bi = 0, bj = 0;
        
        for(int i = 0;i < x;i ++) // 统计需要浏览的 0 数量
            for(int j = 0;j < y;j ++) if(grid[i][j] == 0) count ++;
        
        A:for(; bi < x; bi ++) // 找开始
            for(bj = 0; bj < y; bj ++) if(grid[bi][bj] == 1) break A;

        return recurtion(bi, bj, grid, 0);
    }

    public int recurtion(int bi, int bj, int[][] grid, int c) {
        if(!(bi < 0 || bi == x || bj < 0 || bj == y)) {
            if(grid[bi][bj] == 0 || grid[bi][bj] == 1) {
                grid[bi][bj] = 5; // 当前表示已经浏览过标记
                int cc = c + 1;
                int res = recurtion(bi - 1, bj, grid, cc) 
                    + recurtion(bi + 1, bj, grid, cc) 
                    + recurtion(bi, bj - 1, grid, cc) 
                    + recurtion(bi, bj + 1, grid, cc);
                grid[bi][bj] = 0; // 退出浏览重置 0
                return res;
            } else if(grid[bi][bj] == 2 && c == count) return 1; // 到达终点并且全部 0 浏览
        } return 0;
    }
}

 

 

 

 

 

 

Guess you like

Origin blog.csdn.net/qq_28033719/article/details/109983289