力扣刷题:黑白翻转棋

396 阅读3分钟

前言:锻炼自己的思想,规范自己的编程思路。

问题:

在 n*m 大小的棋盘中,有黑白两种棋子,黑棋记作字母 "X", 白棋记作字母 "O",空余位置记作 "."。当落下的棋子与其他相同颜色的棋子在行、列或对角线完全包围(中间不存在空白位置)另一种颜色的棋子,则可以翻转这些棋子的颜色。

image-20230621222617142.png

「力扣挑战赛」黑白翻转棋项目中,将提供给选手一个未形成可翻转棋子的棋盘残局,其状态记作 chessboard。若下一步可放置一枚黑棋,请问选手最多能翻转多少枚白棋。

注意:

若翻转白棋成黑棋后,棋盘上仍存在可以翻转的白棋,将可以 继续 翻转白棋 输入数据保证初始棋盘状态无可以翻转的棋子且存在空余位置

示例:(放代码里面)

输入:chessboard = ["....X.","....X.","XOOO..","......","......"]

输出:3

解释:
可以选择下在 [2,4] 处,能够翻转白方三枚棋子。

思路:

函数先声明 m 和n获取棋盘的行数和列数 ,并初始化变量 s 为 0。变量 s 用于存储最多能翻转多少枚白棋。然后定义一个二维数组 d,表示八个方向。

接下来,定义了一个名为 BFS 的内部函数,用于在给定位置放置黑棋并计算能翻转多少枚白棋。这个函数接受两个参数sx 和 sy,表示黑棋的位置。

在BFS 函数中,首先创建一个副本G 来存储棋盘状态。然后创建一个队列 q 并将黑棋的位置加入队列。将黑棋放置在给定位置,并初始化变量 t 为 0。变量t 用于存储当前位置能翻转多少枚白棋。

然后进入循环,每次从队列中取出一个位置 [x, y]。对于每个方向,计算下一个位置 [xx, yy] 并检查是否在棋盘内且为白棋。如果是,则继续沿着当前方向搜索,并累加计数器k。如果找到了黑棋,则将计数器累加到变量t中,并将中间的白棋翻转为黑棋。

当队列为空时,循环结束。更新最大翻转数量 s = Math.max(s, t)。

最后,在主函数中遍历整个棋盘,对于每个空位,调用 BFS 函数计算能翻转多少枚白棋。最后返回最大翻转数量 s。

基于上述思考,代码如下:

/**
 * @param {string[]} chessboard
 * @return {number}
 */
var flipChess = function(chessboard) {
  const m = chessboard.length;
  const n = chessboard[0].length;
  let s = 0;
  const d = [[1,0], [1,1], [0,1], [-1,1], [-1,0], [-1,-1], [0,-1], [1,-1]];

  function BFS(sx, sy) {
    let G = chessboard.map(row => row.split(''));
    let q = [[sx, sy]];
    G[sx][sy] = 'X';
    let t = 0;
    while (q.length) {
      const [x, y] = q.shift();
      for (let i = 0; i < 8; i++) {
        const dx = d[i][0];
        const dy = d[i][1];
        let xx = x + dx;
        let yy = y + dy;
        let k = 0;
        while (xx >= 0 && xx < m && yy >= 0 && yy < n && G[xx][yy] === 'O') {
          xx += dx;
          yy += dy;
          k++;
        }
        if (xx >= 0 && xx < m && yy >= 0 && yy < n && G[xx][yy] === 'X') {
          t += k;
          while (k--) {
            xx -= dx;
            yy -= dy;
            q.push([xx, yy]);
            G[xx][yy] = 'X';
          }
        }
      }
    }
    s = Math.max(s, t);
  }

  for (let i = 0; i < m; i++) {
    for (let j = 0; j < n; j++) {
      if (chessboard[i][j] === '.') {
        BFS(i, j);
      }
    }
  }

  return s;
}

执行结果如下图:

image-20230621224053497.png