51
51
52
52
<!-- 这里可写通用的实现逻辑 -->
53
53
54
- 动态规划。` dp[l][i][j] ` 表示骑士从 ` (i, j) ` 出发,走了 l 步后,仍留在棋盘上的概率。
54
+ ** 方法一:动态规划**
55
+
56
+ 我们定义 $f[ h] [ i ] [ j] $ 表示骑士从 $(i, j)$ 位置出发,走了 $h$ 步以后还留在棋盘上的概率。那么最终答案就是 $f[ k] [ row ] [ column] $。
57
+
58
+ 当 $h=0$ 时,骑士一定在棋盘上,概率为 $1$,即 $f[ 0] [ i ] [ j] =1$。
59
+
60
+ 当 $h \gt 0$ 时,骑士在 $(i, j)$ 位置上的概率可以由其上一步的 $8$ 个位置上的概率转移得到,即:
61
+
62
+ $$
63
+ f[h][i][j] = \sum_{a, b} f[h - 1][a][b] \times \frac{1}{8}
64
+ $$
65
+
66
+ 其中 $(a, b)$ 是从 $(i, j)$ 位置可以走到的 $8$ 个位置中的一个。
67
+
68
+ 最终答案即为 $f[ k] [ row ] [ column] $。
69
+
70
+ 时间复杂度 $O(k \times n^2)$,空间复杂度 $O(k \times n^2)$。其中 $k$ 和 $n$ 分别是给定的步数和棋盘大小。
55
71
56
72
<!-- tabs:start -->
57
73
62
78
``` python
63
79
class Solution :
64
80
def knightProbability (self , n : int , k : int , row : int , column : int ) -> float :
65
- dp = [[[0 ] * n for _ in range (n)] for _ in range (k + 1 )]
66
- for l in range (k + 1 ):
81
+ f = [[[0 ] * n for _ in range (n)] for _ in range (k + 1 )]
82
+ for i in range (n):
83
+ for j in range (n):
84
+ f[0 ][i][j] = 1
85
+ for h in range (1 , k + 1 ):
67
86
for i in range (n):
68
87
for j in range (n):
69
- if l == 0 :
70
- dp[l][i][j] = 1
71
- else :
72
- for a, b in (
73
- (- 2 , - 1 ),
74
- (- 2 , 1 ),
75
- (2 , - 1 ),
76
- (2 , 1 ),
77
- (- 1 , - 2 ),
78
- (- 1 , 2 ),
79
- (1 , - 2 ),
80
- (1 , 2 ),
81
- ):
82
- x, y = i + a, j + b
83
- if 0 <= x < n and 0 <= y < n:
84
- dp[l][i][j] += dp[l - 1 ][x][y] / 8
85
- return dp[k][row][column]
88
+ for a, b in pairwise((- 2 , - 1 , 2 , 1 , - 2 , 1 , 2 , - 1 , - 2 )):
89
+ x, y = i + a, j + b
90
+ if 0 <= x < n and 0 <= y < n:
91
+ f[h][i][j] += f[h - 1 ][x][y] / 8
92
+ return f[k][row][column]
86
93
```
87
94
88
95
### ** Java**
@@ -92,68 +99,27 @@ class Solution:
92
99
``` java
93
100
class Solution {
94
101
public double knightProbability (int n , int k , int row , int column ) {
95
- double [][][] dp = new double [k + 1 ][n][n];
102
+ double [][][] f = new double [k + 1 ][n][n];
103
+ for (int i = 0 ; i < n; ++ i) {
104
+ for (int j = 0 ; j < n; ++ j) {
105
+ f[0 ][i][j] = 1 ;
106
+ }
107
+ }
96
108
int [] dirs = {- 2 , - 1 , 2 , 1 , - 2 , 1 , 2 , - 1 , - 2 };
97
- for (int l = 0 ; l <= k; ++ l ) {
109
+ for (int h = 1 ; h <= k; ++ h ) {
98
110
for (int i = 0 ; i < n; ++ i) {
99
111
for (int j = 0 ; j < n; ++ j) {
100
- if (l == 0 ) {
101
- dp[l][i][j] = 1 ;
102
- } else {
103
- for (int d = 0 ; d < 8 ; ++ d) {
104
- int x = i + dirs[d], y = j + dirs[d + 1 ];
105
- if (x >= 0 && x < n && y >= 0 && y < n) {
106
- dp[l][i][j] += dp[l - 1 ][x][y] / 8 ;
107
- }
108
- }
109
- }
110
- }
111
- }
112
- }
113
- return dp[k][row][column];
114
- }
115
- }
116
- ```
117
-
118
- ### ** TypeScript**
119
-
120
- ``` ts
121
- function knightProbability(
122
- n : number ,
123
- k : number ,
124
- row : number ,
125
- column : number ,
126
- ): number {
127
- let dp = Array .from ({ length: k + 1 }, v =>
128
- Array .from ({ length: n }, w => new Array (n ).fill (0 )),
129
- );
130
- const directions = [
131
- [- 2 , - 1 ],
132
- [- 2 , 1 ],
133
- [- 1 , - 2 ],
134
- [- 1 , 2 ],
135
- [1 , - 2 ],
136
- [1 , 2 ],
137
- [2 , - 1 ],
138
- [2 , 1 ],
139
- ];
140
- for (let depth = 0 ; depth <= k ; depth ++ ) {
141
- for (let i = 0 ; i < n ; i ++ ) {
142
- for (let j = 0 ; j < n ; j ++ ) {
143
- if (! depth ) {
144
- dp [depth ][i ][j ] = 1 ;
145
- } else {
146
- for (let [dx, dy] of directions ) {
147
- let [x, y] = [i + dx , j + dy ];
112
+ for (int p = 0 ; p < 8 ; ++ p) {
113
+ int x = i + dirs[p], y = j + dirs[p + 1 ];
148
114
if (x >= 0 && x < n && y >= 0 && y < n) {
149
- dp [ depth ][i ][j ] += dp [ depth - 1 ][x ][y ] / 8 ;
115
+ f[h ][i][j] += f[h - 1 ][x][y] / 8 ;
150
116
}
151
117
}
152
118
}
153
119
}
154
120
}
121
+ return f[k][row][column];
155
122
}
156
- return dp [k ][row ][column ];
157
123
}
158
124
```
159
125
@@ -163,24 +129,27 @@ function knightProbability(
163
129
class Solution {
164
130
public:
165
131
double knightProbability(int n, int k, int row, int column) {
166
- vector<vector<vector<double >>> dp(k + 1, vector<vector<double >>(n, vector<double >(n)));
167
- vector<int > dirs = {-2, -1, 2, 1, -2, 1, 2, -1, -2};
168
- for (int l = 0; l <= k; ++l) {
132
+ double f[ k + 1] [ n ] [ n] ;
133
+ memset(f, 0, sizeof(f));
134
+ for (int i = 0; i < n; ++i) {
135
+ for (int j = 0; j < n; ++j) {
136
+ f[ 0] [ i ] [ j] = 1;
137
+ }
138
+ }
139
+ int dirs[ 9] = {-2, -1, 2, 1, -2, 1, 2, -1, -2};
140
+ for (int h = 1; h <= k; ++h) {
169
141
for (int i = 0; i < n; ++i) {
170
142
for (int j = 0; j < n; ++j) {
171
- if (l == 0)
172
- dp[ l] [ i ] [ j] = 1;
173
- else {
174
- for (int d = 0; d < 8; ++d) {
175
- int x = i + dirs[ d] , y = j + dirs[ d + 1] ;
176
- if (x >= 0 && x < n && y >= 0 && y < n)
177
- dp[ l] [ i ] [ j] += dp[ l - 1] [ x ] [ y] / 8;
143
+ for (int p = 0; p < 8; ++p) {
144
+ int x = i + dirs[ p] , y = j + dirs[ p + 1] ;
145
+ if (x >= 0 && x < n && y >= 0 && y < n) {
146
+ f[ h] [ i ] [ j] += f[ h - 1] [ x ] [ y] / 8;
178
147
}
179
148
}
180
149
}
181
150
}
182
151
}
183
- return dp [ k] [ row ] [ column] ;
152
+ return f [ k] [ row ] [ column] ;
184
153
}
185
154
};
186
155
```
@@ -189,27 +158,65 @@ public:
189
158
190
159
```go
191
160
func knightProbability(n int, k int, row int, column int) float64 {
192
- dp := make([][][]float64, k+1)
193
- dirs := []int{-2, -1, 2, 1, -2, 1, 2, -1, -2}
194
- for l := range dp {
195
- dp[l] = make([][]float64, n)
161
+ f := make([][][]float64, k+1)
162
+ for h := range f {
163
+ f[h] = make([][]float64, n)
164
+ for i := range f[h] {
165
+ f[h][i] = make([]float64, n)
166
+ for j := range f[h][i] {
167
+ f[0][i][j] = 1
168
+ }
169
+ }
170
+ }
171
+ dirs := [9]int{-2, -1, 2, 1, -2, 1, 2, -1, -2}
172
+ for h := 1; h <= k; h++ {
196
173
for i := 0; i < n; i++ {
197
- dp[l][i] = make([]float64, n)
198
174
for j := 0; j < n; j++ {
199
- if l == 0 {
200
- dp[l][i][j] = 1
201
- } else {
202
- for d := 0; d < 8; d++ {
203
- x, y := i+dirs[d], j+dirs[d+1]
204
- if 0 <= x && x < n && 0 <= y && y < n {
205
- dp[l][i][j] += dp[l-1][x][y] / 8
206
- }
175
+ for p := 0; p < 8; p++ {
176
+ x, y := i+dirs[p], j+dirs[p+1]
177
+ if x >= 0 && x < n && y >= 0 && y < n {
178
+ f[h][i][j] += f[h-1][x][y] / 8
207
179
}
208
180
}
209
181
}
210
182
}
211
183
}
212
- return dp[k][row][column]
184
+ return f[k][row][column]
185
+ }
186
+ ```
187
+
188
+ ### ** TypeScript**
189
+
190
+ ``` ts
191
+ function knightProbability(
192
+ n : number ,
193
+ k : number ,
194
+ row : number ,
195
+ column : number ,
196
+ ): number {
197
+ const f = new Array (k + 1 )
198
+ .fill (0 )
199
+ .map (() => new Array (n ).fill (0 ).map (() => new Array (n ).fill (0 )));
200
+ for (let i = 0 ; i < n ; ++ i ) {
201
+ for (let j = 0 ; j < n ; ++ j ) {
202
+ f [0 ][i ][j ] = 1 ;
203
+ }
204
+ }
205
+ const dirs = [- 2 , - 1 , 2 , 1 , - 2 , 1 , 2 , - 1 , - 2 ];
206
+ for (let h = 1 ; h <= k ; ++ h ) {
207
+ for (let i = 0 ; i < n ; ++ i ) {
208
+ for (let j = 0 ; j < n ; ++ j ) {
209
+ for (let p = 0 ; p < 8 ; ++ p ) {
210
+ const x = i + dirs [p ];
211
+ const y = j + dirs [p + 1 ];
212
+ if (x >= 0 && x < n && y >= 0 && y < n ) {
213
+ f [h ][i ][j ] += f [h - 1 ][x ][y ] / 8 ;
214
+ }
215
+ }
216
+ }
217
+ }
218
+ }
219
+ return f [k ][row ][column ];
213
220
}
214
221
```
215
222
0 commit comments