[Leetcode] 688. Knight Probability in Chessboard 解题报告
2018-02-02 21:07
393 查看
题目:
On an
a knight starts at the
column and attempts to make exactly
top-left square is
A chess knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal direction, then one square in an orthogonal direction.
Each time the knight is to move, it chooses one of eight possible moves uniformly at random (even if the piece would go off the chessboard) and moves there.
The knight continues moving until it has made exactly
Return the probability that the knight remains on the board after it has stopped moving.
Example:
Note:
The knight always initially starts on the board.
思路:
我们定义一个映射map<pos, prob> status,将位置映射到其出现的概率上。对于每个pos而言,它可以到达8个不同的位置。而到这8个位置的概率都是status[pos] * 1 / 8。我们分别计算这8个位置,如果发现它还在棋盘的范围之内,就将其概率增加status[pos] * 1 / 8。当行走K步之后,我们将status中的所有概率加起来,即为knight最后留在棋盘上的概率。
在实现中,为了避免开辟过大的空间以及频繁的赋值操作引起效率降低,我们定义status_even和status_odd,用来交替更新数据。这样算法的时间复杂度就是O(KN^2),空间复杂度可以降低到O(N^2)。
代码:
class Solution {
public:
double knightProbability(int N, int K, int r, int c) {
map<vector<int>, double> status_even, status_odd;
status_even[{r, c}] = 1.0;
for (int i = 0; i < K; ++i) {
if (i % 2 == 0) {
status_odd.clear();
for (auto it = status_even.begin(); it != status_even.end(); ++it) {
movePositions(N, it->first[0], it->first[1], it->second, status_odd);
}
}
else {
status_even.clear();
for (auto it = status_odd.begin(); it != status_odd.end(); ++it) {
movePositions(N, it->first[0], it->first[1], it->second, status_even);
}
}
}
map<vector<int>, double>::iterator begin = K % 2 == 0 ? status_even.begin() : status_odd.begin();
map<vector<int>, double>::iterator end = K % 2 == 0 ? status_even.end() : status_odd.end();
double ret = 0;
for (auto it = begin; it != end; ++it) {
ret += it->second;
}
return ret;
}
private:
void movePositions(int N, int r, int c, double value, map<vector<int>, double> &positions) {
vector<vector<int>> next_pos;
if (r + 2 < N) {
if (c + 1 < N) {
next_pos.push_back({r + 2, c + 1});
}
if (c - 1 >= 0) {
next_pos.push_back({r + 2, c - 1});
}
}
if (r - 2 >= 0) {
if (c + 1 < N) {
next_pos.push_back({r - 2, c + 1});
}
if (c - 1 >= 0) {
next_pos.push_back({r - 2, c - 1});
}
}
if (r + 1 < N) {
if (c + 2 < N) {
next_pos.push_back({r + 1, c + 2});
}
if (c - 2 >= 0) {
next_pos.push_back({r + 1, c - 2});
}
}
if (r - 1 >= 0) {
if (c + 2 < N) {
next_pos.push_back({r - 1, c + 2});
}
if (c - 2 >= 0) {
next_pos.push_back({r - 1, c - 2});
}
}
for (auto &p : next_pos) {
positions[p] += value / 8.0;
}
}
};
On an
Nx
Nchessboard,
a knight starts at the
r-th row and
c-th
column and attempts to make exactly
Kmoves. The rows and columns are 0 indexed, so the
top-left square is
(0, 0), and the bottom-right square is
(N-1, N-1).
A chess knight has 8 possible moves it can make, as illustrated below. Each move is two squares in a cardinal direction, then one square in an orthogonal direction.
Each time the knight is to move, it chooses one of eight possible moves uniformly at random (even if the piece would go off the chessboard) and moves there.
The knight continues moving until it has made exactly
Kmoves or has moved off the chessboard.
Return the probability that the knight remains on the board after it has stopped moving.
Example:
Input: 3, 2, 0, 0 Output: 0.0625 Explanation: There are two moves (to (1,2), (2,1)) that will keep the knight on the board. From each of those positions, there are also two moves that will keep the knight on the board. The total probability the knight stays on the board is 0.0625.
Note:
Nwill be between 1 and 25.
Kwill be between 0 and 100.
The knight always initially starts on the board.
思路:
我们定义一个映射map<pos, prob> status,将位置映射到其出现的概率上。对于每个pos而言,它可以到达8个不同的位置。而到这8个位置的概率都是status[pos] * 1 / 8。我们分别计算这8个位置,如果发现它还在棋盘的范围之内,就将其概率增加status[pos] * 1 / 8。当行走K步之后,我们将status中的所有概率加起来,即为knight最后留在棋盘上的概率。
在实现中,为了避免开辟过大的空间以及频繁的赋值操作引起效率降低,我们定义status_even和status_odd,用来交替更新数据。这样算法的时间复杂度就是O(KN^2),空间复杂度可以降低到O(N^2)。
代码:
class Solution {
public:
double knightProbability(int N, int K, int r, int c) {
map<vector<int>, double> status_even, status_odd;
status_even[{r, c}] = 1.0;
for (int i = 0; i < K; ++i) {
if (i % 2 == 0) {
status_odd.clear();
for (auto it = status_even.begin(); it != status_even.end(); ++it) {
movePositions(N, it->first[0], it->first[1], it->second, status_odd);
}
}
else {
status_even.clear();
for (auto it = status_odd.begin(); it != status_odd.end(); ++it) {
movePositions(N, it->first[0], it->first[1], it->second, status_even);
}
}
}
map<vector<int>, double>::iterator begin = K % 2 == 0 ? status_even.begin() : status_odd.begin();
map<vector<int>, double>::iterator end = K % 2 == 0 ? status_even.end() : status_odd.end();
double ret = 0;
for (auto it = begin; it != end; ++it) {
ret += it->second;
}
return ret;
}
private:
void movePositions(int N, int r, int c, double value, map<vector<int>, double> &positions) {
vector<vector<int>> next_pos;
if (r + 2 < N) {
if (c + 1 < N) {
next_pos.push_back({r + 2, c + 1});
}
if (c - 1 >= 0) {
next_pos.push_back({r + 2, c - 1});
}
}
if (r - 2 >= 0) {
if (c + 1 < N) {
next_pos.push_back({r - 2, c + 1});
}
if (c - 1 >= 0) {
next_pos.push_back({r - 2, c - 1});
}
}
if (r + 1 < N) {
if (c + 2 < N) {
next_pos.push_back({r + 1, c + 2});
}
if (c - 2 >= 0) {
next_pos.push_back({r + 1, c - 2});
}
}
if (r - 1 >= 0) {
if (c + 2 < N) {
next_pos.push_back({r - 1, c + 2});
}
if (c - 2 >= 0) {
next_pos.push_back({r - 1, c - 2});
}
}
for (auto &p : next_pos) {
positions[p] += value / 8.0;
}
}
};
相关文章推荐
- 【LeetCode】1. Two Sum 解题报告
- 【LeetCode】Binary Tree Preorder Traversal 解题报告
- [leetcode] 3. Longest Substring Without Repeating Characters 解题报告
- 【LeetCode】Balanced Binary Tree 解题报告
- [leetcode] 296. Best Meeting Point 解题报告
- [leetcode] 186. Reverse Words in a String II 解题报告
- 【LeetCode】Construct the Rectangle 解题报告
- 【LeetCode】655. Print Binary Tree 解题报告(Python)
- 【LeetCode】Longest Palindromic Substring 解题报告
- LeetCode Convert Sorted List to Binary Search Tree 解题报告
- Leetcode 393. UTF-8 Validation UTF-8 编码识别 解题报告
- [leetcode] 375. Guess Number Higher or Lower II 解题报告
- [Leetcode] 34. Search for a Range 解题报告
- Leetcode 152-MaximumProductSubarray 解题报告
- LeetCode 解题报告 3Sum Closest
- LeetCode Intersection of Two Linked Lists 解题报告
- [LeetCode 解题报告]006.ZigZag Conversion
- [Leetcode] 432. All O`one Data Structure 解题报告
- [leetcode] 213. House Robber II 解题报告
- [leetcode] 172. Factorial Trailing Zeroes 解题报告