999. Available Captures for Rook

On an 8 x 8 chessboard, there is one white rook.  There also may be empty squares, white bishops, and black pawns.  These are given as characters ‘R’, ‘.’, ‘B’, and ‘p’ respectively. Uppercase characters represent white pieces, and lowercase characters represent black pieces.

The rook moves as in the rules of Chess: it chooses one of four cardinal directions (north, east, west, and south), then moves in that direction until it chooses to stop, reaches the edge of the board, or captures an opposite colored pawn by moving to the same square it occupies.  Also, rooks cannot move into the same square as other friendly bishops.

Return the number of pawns the rook can capture in one move.

Example 1:

Input: [[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".","R",".",".",".","p"],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."]]
Output: 3
Explanation:
In this example the rook is able to capture all the pawns.

Example 2:

Input: [[".",".",".",".",".",".",".","."],[".","p","p","p","p","p",".","."],[".","p","p","B","p","p",".","."],[".","p","B","R","B","p",".","."],[".","p","p","B","p","p",".","."],[".","p","p","p","p","p",".","."],[".",".",".",".",".",".",".","."],[".",".",".",".",".",".",".","."]]
Output: 0
Explanation:
Bishops are blocking the rook to capture any pawn.

Example 3:

Input: [[".",".",".",".",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".","p",".",".",".","."],["p","p",".","R",".","p","B","."],[".",".",".",".",".",".",".","."],[".",".",".","B",".",".",".","."],[".",".",".","p",".",".",".","."],[".",".",".",".",".",".",".","."]]
Output: 3
Explanation:
The rook can capture the pawns at positions b5, d6 and f5.

Note:

  1. board.length == board[i].length == 8
  2. board[i][j] is either 'R''.''B', or 'p'
  3. There is exactly one cell with board[i][j] == 'R'

这道题给了一个 8x8 大小的国际象棋棋盘,上面只能有三种棋子,分别是白方的车,白方的象,和黑方的兵,问白色方的车最多能吃到多个黑方的兵。在国际象棋中,车是可以上下左右走的,若某条路径上先遇到了白方的象,则该路上没法吃兵了,若先遇上了兵,可以吃,但此时后面若还有兵,不能连续吃。搞懂了题意其实很简单了,首先遍历棋盘,找到白方车的位置,然后最简单粗暴的方法是,四个方向分别用 for 循环来遍历,若遇到白方的象,直接 break,若遇到兵,则结果 res 自增1,然后 break 即可,参见代码如下:

解法一:

class Solution {
public:
    int numRookCaptures(vector<vector<char>>& board) {
        int x = 0, y = 0, res = 0;
        for (int i = 0; i < 8; ++i) {
            for (int j = 0; j < 8; ++j) {
                if (board[i][j] == 'R') {
                    x = i; y = j; break;
                }
            }
        }
        for (int j = y; j >= 0; --j) {
            if (board[x][j] == 'B') break;
            if (board[x][j] == 'p') {++res; break;} 
        }
        for (int j = y; j < 8; ++j) {
            if (board[x][j] == 'B') break;
            if (board[x][j] == 'p') {++res; break;}  
        }
        for (int i = x; i >= 0; --i) {
            if (board[i][y] == 'B') break;
            if (board[i][y] == 'p') {++res; break;} 
        }
        for (int i = x; i < 8; ++i) {
            if (board[i][y] == 'B') break;
            if (board[i][y] == 'p') {++res; break;} 
        }
        return res;
    }
};

我们也可以不用写那么 for 循环,而是利用深度优先遍历 DFS 的思想,用方向数组,每次加上方向的偏移,若没有越界,则判断,若是黑兵,则结果 res 加1,若不是点,则 break,这判断很精髓,覆盖了当前是白象或黑兵的情况,保证了遇到了白象,或者已经吃了黑兵之后可以 break,然后继续增加偏移量直至退出循环,参见代码如下:

解法二:

class Solution {
public:
    int numRookCaptures(vector<vector<char>>& board) {
        int x0 = 0, y0 = 0, res = 0;
        vector<vector<int>> dirs{{-1, 0}, {0, 1}, {1, 0}, {0, -1}};
        for (int i = 0; i < 8; ++i) {
            for (int j = 0; j < 8; ++j) {
                if (board[i][j] == 'R') {
                    x0 = i; y0 = j; break;
                }
            }
        }
        for (auto &dir : dirs) {
            int x = x0 + dir[0], y = y0 + dir[1];
            while (x >= 0 && x < 8 && y >= 0 && y < 8) {
                if (board[x][y] == 'p') ++res;
                if (board[x][y] != '.') break;
                x += dir[0]; y += dir[1];
            }
        }
        return res;
    }
};

Github 同步地址:

https://github.com/grandyang/leetcode/issues/999

参考资料:

https://leetcode.com/problems/available-captures-for-rook/

https://leetcode.com/problems/available-captures-for-rook/discuss/242924/C%2B%2BJava-search-and-capture

https://leetcode.com/problems/available-captures-for-rook/discuss/242932/JavaC%2B%2BPython-Straight-Forward-Solution

LeetCode All in One 题目讲解汇总(持续更新中…)


转载请注明来源于 Grandyang 的博客 (grandyang.com),欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 grandyang@qq.com

💰


微信打赏


Venmo 打赏

(欢迎加入博主的知识星球,博主将及时答疑解惑,并分享刷题经验与总结,试运营期间前五十位可享受半价优惠~)

×

Help us with donation