980. 不同路径 III

在二维网格 grid 上,有 4 种类型的方格:

1 表示起始方格。且只有一个起始方格。
2 表示结束方格,且只有一个结束方格。
0 表示我们可以走过的空方格。
-1 表示我们无法跨越的障碍。
返回在四个方向(上、下、左、右)上行走时,从起始方格到结束方格的不同路径的数目。

每一个无障碍方格都要通过一次,但是一条路径中不能重复通过同一个方格。

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/unique-paths-iii
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

深度优先搜索

import java.util.HashSet;
import java.util.Objects;
import java.util.Set;

class Solution {

    private int ans = 0;

    private int[][] directions = {{1, 0}, {0, 1}, {-1, 0}, {0, -1}};

    private void solve(int[][] grid, Pair from, Pair end, int total) {
        if (total < 0) {
            return;
        }

        if (total == 0 || from.equals(end)) {
            if (total == 0 && from.equals(end)) {
                ans++;
            }
            return;
        }

        for (int i = 0; i < directions.length; ++i) {
            int x = from.x + directions[i][0];
            int y = from.y + directions[i][1];
            Pair to = new Pair(x, y);
            if (x >= 0 && x < grid.length && y >= 0 && y < grid[0].length && grid[x][y] != -1) {
                int t = grid[x][y];
                grid[x][y] = -1;
                solve(grid, to, end, total - 1);
                grid[x][y] = t;
            }
        }
    }

    public int uniquePathsIII(int[][] grid) {
        Pair start = null, end = null;
        int total = grid.length * grid[0].length;
        for (int i = 0; i < grid.length; ++i) {
            for (int j = 0; j < grid[0].length; ++j) {
                if (grid[i][j] == 1) {
                    start = new Pair(i, j);
                } else if (grid[i][j] == 2) {
                    end = new Pair(i, j);
                } else if (grid[i][j] == -1) {
                    total--;
                }
            }
        }
        grid[start.x][start.y] = -1;
        solve(grid, start, end, total - 1);
        return ans;
    }

    public static void main(String[] args) {
        int[][] grid = {
                {1, 0, 0, 0},
                {0, 0, 0, 0},
                {0, 0, 2, -1}};
        System.out.println(new Solution().uniquePathsIII(grid));
    }
}

class Pair {
    int x;
    int y;

    public Pair(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public boolean equals(Object o) {
        if (this == o) return true;
        if (o == null || getClass() != o.getClass()) return false;
        Pair pair = (Pair) o;
        return x == pair.x && y == pair.y;
    }

    @Override
    public int hashCode() {
        return Objects.hash(x, y);
    }
}

动态规划

class Solution {
    private int[][] grid;
    private int tr, tc;
    private int[][] directions = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
    private Integer[][][] memo;

    public int uniquePathsIII(int[][] grid) {
        this.grid = grid;
        int target = 0;

        int sr = 0, sc = 0;
        for (int r = 0; r < grid.length; ++r)
            for (int c = 0; c < grid[0].length; ++c) {
                if (grid[r][c] % 2 == 0) {
                    target |= code(r, c);
                }

                if (grid[r][c] == 1) {
                    sr = r;
                    sc = c;
                } else if (grid[r][c] == 2) {
                    tr = r;
                    tc = c;
                }
            }

        memo = new Integer[grid.length][grid[0].length][1 << (grid.length * grid[0].length)];
        return dp(sr, sc, target);
    }

    public int code(int r, int c) {
        return 1 << (r * grid[0].length + c);
    }

    public Integer dp(int r, int c, int todo) {
        if (memo[r][c][todo] == null) {
            if (r == tr && c == tc) {
                memo[r][c][todo] = todo == 0 ? 1 : 0;
            } else {
                int ans = 0;
                for (int k = 0; k < 4; ++k) {
                    int nr = r + directions[k][0];
                    int nc = c + directions[k][1];
                    if (0 <= nr && nr < grid.length && 0 <= nc && nc < grid[0].length) {
                        if ((todo & code(nr, nc)) != 0) {
                            ans += dp(nr, nc, todo ^ code(nr, nc));
                        }
                    }
                }
                memo[r][c][todo] = ans;
            }
        }
        return memo[r][c][todo];
    }
}
posted @ 2022-02-11 14:35  Tianyiya  阅读(41)  评论(0)    收藏  举报