问题描述
给定一个 n x n 的整数矩阵 board 表示一个棋盘。我们用黑白棋子来表示这个棋盘,其中 0 代表一个黑棋,1 代表一个白棋。棋盘的行数 n 为奇数,且 n x n 的棋盘有 n^2 个格子,其中一半黑棋,一半白棋,即 n^2 / 2 个黑棋和 n^2 / 2 个白棋。
任务是将棋盘转换为按行和列黑白交替出现的棋盘。返回最少需要翻转的格子数。
示例 1: 输入: board = [[0,1,1],[1,0,1],[1,1,0]] 输出: 2 解释: 第一个示例如下,翻转位于(1,2)和(2,1)的棋子后棋盘变为: 从左到右,从上到下: [0, 1, 1] [0, 0, 0] [1, 1, 1]
示例 2: 输入: board = [[0,1],[1,0]] 输出: 1 解释: 翻转位于(0,1)的棋子后棋盘变为: 从左到右,从上到下: [0, 0] [1, 1]
示例 3: 输入: board = [[1,0],[0,1]] 输出: 0 解释: 棋盘已经是按行和列黑白交替出现的棋盘。
注意:
- n 是奇数。
- board[i][j] 总是 0 或 1。
- 每次翻转都会改变棋盘上两个格子的颜色。因此,翻转次数一定是偶数。
解法一
解题思路:
我们可以通过计算每一行和每一列的黑白棋子数量,然后计算出需要翻转的棋子数量。具体来说,对于每一行和每一列,我们计算出与期望颜色不同的棋子数量,然后取两者的最小值作为翻转次数。
/*
* @lc app=leetcode.cn id=782 lang=javascript
*
* [782] Transform to Chessboard
*/
// @lc code=start
function movesToChessboard(board) {
const n = board.length;
let rowXor = 0, colXor = 0;
let rowOnes = 0, colOnes = 0;
for (let i = 0; i < n; i++) {
rowXor ^= i % 2 === 0 ? 1 : 0;
colXor ^= i % 2 === 0 ? 0 : 1;
for (let j = 0; j < n; j++) {
if (board[i][j] === 0) continue;
rowOnes++;
if (j % 2 === 0 ? board[i][j] === 0 : board[i][j] === 1) colXor ^= 1;
if (i % 2 === 0 ? board[i][j] === 0 : board[i][j] === 1) rowXor ^= 1;
}
}
const total = (n * n) / 2;
const rowFlips = rowOnes === total ? n - rowOnes : rowOnes;
const colFlips = (n * n - rowOnes) / 2;
if (rowXor !== colXor) return -1;
return rowFlips + colFlips;
}
// @lc code=end