LeetCode 688. 骑士在棋盘上的概率

92 阅读1分钟

这是我参与2022首次更文挑战的第3天,活动详情查看:2022首次更文挑战

leetcode地址: leetcode-cn.com/problems/kn…

image.png

思路1: 记忆化搜索, 原文地址:

public class Solution {
    // 移动轨迹
    private static final int[][] dirs = { { 1, 2 }, { 2, 1 }, { -1, 2 }, { 2, -1 }, { 1, -2 },  -2, 1 }, { -1, -2 }, { -2, -1 } };

    public double knightProbability(int n, int k, int row, int column) {
        double[][][] memo = new double[n][n][k + 1];
        return dfs(n, k, row, column, memo);
    }

    public double dfs(int n, int k, int row, int column, double[][][] memo) {
        if (row < 0 || column < 0 || row >= n || column >= n) {
            return 0;
        }
        if (k == 0) {
            return 1;
        }
        if (memo[row][column][k] != 0) {
            return memo[row][column][k];
        }
        double ans = 0;
        for (int i = 0; i < dirs.length; i++) {
            ans += dfs(n, k - 1, row + dirs[i][0], column + dirs[i][1], memo) / 8.0;
        }
        memo[row][column][k] = ans;
        return ans;
    }
}

思路2: 动态规划

public class Solution {
    private static final int[][] dirs = { { 1, 2 }, { 2, 1 }, { -1, 2 }, { 2, -1 }, { 1, -2 }, { -2, 1 }, { -1, -2 },
            { -2, -1 } };

    public double knightProbability(int n, int k, int row, int column) {
        double[][][] dp = new double[n][n][k + 1];
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                dp[i][j][0] = 1;
            }
        }
        // 从0起
        for (int kk = 1; kk <= k; kk++) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    for (int[] dir : dirs) {
                        int nx = dir[0] + i;
                        int ny = dir[1] + j;
                        if (nx >= 0 && ny >= 0 && nx < n && ny < n)
                            dp[i][j][kk] += dp[nx][ny][kk - 1] / 8.0;
                    }
                }
            }
        }

        return dp[row][column][k];
    }
}