Knight Probability in Chessboard

medium dp probability

Problem

Knight starts at (r, c) on n×n board. After k random L-moves, return probability it's still on the board.

Inputn=3 k=2 r=0 c=0
Output0.0625
Two moves at random has small survival probability.

def knight_prob(n, k, r, c):
    dp = [[0.0] * n for _ in range(n)]; dp[r][c] = 1.0
    moves = [(2,1),(2,-1),(-2,1),(-2,-1),(1,2),(1,-2),(-1,2),(-1,-2)]
    for _ in range(k):
        nxt = [[0.0] * n for _ in range(n)]
        for i in range(n):
            for j in range(n):
                if dp[i][j] == 0: continue
                for dr, dc in moves:
                    ni, nj = i + dr, j + dc
                    if 0 <= ni < n and 0 <= nj < n: nxt[ni][nj] += dp[i][j] / 8
        dp = nxt
    return sum(sum(row) for row in dp)
function knightProbability(n, k, r, c) {
  let dp = Array.from({length: n}, () => new Array(n).fill(0)); dp[r][c] = 1;
  const moves = [[2,1],[2,-1],[-2,1],[-2,-1],[1,2],[1,-2],[-1,2],[-1,-2]];
  for (let s = 0; s < k; s++) {
    const nx = Array.from({length: n}, () => new Array(n).fill(0));
    for (let i = 0; i < n; i++) for (let j = 0; j < n; j++) {
      if (!dp[i][j]) continue;
      for (const [dr, dc] of moves) {
        const ni = i + dr, nj = j + dc;
        if (ni >= 0 && ni < n && nj >= 0 && nj < n) nx[ni][nj] += dp[i][j] / 8;
      }
    }
    dp = nx;
  }
  return dp.flat().reduce((a, b) => a + b, 0);
}
double knightProbability(int n, int k, int r, int c) {
    double[][] dp = new double[n][n]; dp[r][c] = 1;
    int[][] moves = {{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{1,-2},{-1,2},{-1,-2}};
    for (int s = 0; s < k; s++) {
        double[][] nx = new double[n][n];
        for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {
            if (dp[i][j] == 0) continue;
            for (int[] m : moves) {
                int ni = i + m[0], nj = j + m[1];
                if (ni >= 0 && ni < n && nj >= 0 && nj < n) nx[ni][nj] += dp[i][j] / 8;
            }
        }
        dp = nx;
    }
    double tot = 0; for (double[] row : dp) for (double v : row) tot += v; return tot;
}
double knightProbability(int n, int k, int r, int c) {
    vector> dp(n, vector(n, 0)); dp[r][c] = 1;
    int moves[8][2] = {{2,1},{2,-1},{-2,1},{-2,-1},{1,2},{1,-2},{-1,2},{-1,-2}};
    for (int s = 0; s < k; s++) {
        vector> nx(n, vector(n, 0));
        for (int i = 0; i < n; i++) for (int j = 0; j < n; j++) {
            if (!dp[i][j]) continue;
            for (auto& m : moves) {
                int ni = i + m[0], nj = j + m[1];
                if (ni >= 0 && ni < n && nj >= 0 && nj < n) nx[ni][nj] += dp[i][j] / 8;
            }
        }
        dp = nx;
    }
    double tot = 0; for (auto& row : dp) for (double v : row) tot += v; return tot;
}
Time: O(k·n²) Space: O(n²)