题目描述
一个 n x n
的二维网络 board
仅由 0
和 1
组成 。每次移动,你能任意交换两列或是两行的位置。
返回 将这个矩阵变为 “棋盘” 所需的最小移动次数 。如果不存在可行的变换,输出 -1
。
“棋盘” 是指任意一格的上下左右四个方向的值均与本身不同的矩阵。
示例
示例 1:

1 2 3 4 5
| 输入: board = [[0,1,1,0],[0,1,1,0],[1,0,0,1],[1,0,0,1]] 输出: 2 解释:一种可行的变换方式如下,从左到右: 第一次移动交换了第一列和第二列。 第二次移动交换了第二行和第三行。
|
示例 2:

1 2 3
| 输入: board = [[0, 1], [1, 0]] 输出: 0 解释: 注意左上角的格值为0时也是合法的棋盘,也是合法的棋盘.
|
示例 3:

1 2 3
| 输入: board = [[1, 0], [1, 0]] 输出: -1 解释: 任意的变换都不能使这个输入变为合法的棋盘。
|
提示:
1 2 3 4
| n == board.length n == board[i].length 2 <= n <= 30 board[i][j] 将只包含 `0`或 `1`
|
代码
只有 c++ 版本有详细注释,其它都是仿照 c++ 版本写的!
分维度计算 (c++)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105
|
class Solution { public: int getOneCnt(int mask, int n) { int res = 0; for (int i = 0; i < n; ++i) { res += mask & 0x01; mask >>= 1; } return res; }
int getMoveCnt(int mask, int cnt, int n) { int mask_one_cnt = getOneCnt(mask, n);
if (!(n % 2)) { if ((n / 2) != mask_one_cnt || (n / 2) != cnt) { return -1; } int cnt0 = n / 2 - getOneCnt(mask & 0xaaaaaaaa, 32); int cnt1 = n / 2 - getOneCnt(mask & 0x55555555, 32); return cnt0 < cnt1 ? cnt0 : cnt1; } else { int ym = n - mask_one_cnt * 2, yc = n - cnt * 2; ym = ym < 0 ? -ym : ym; yc = yc < 0 ? -yc : yc; if (ym != 1 || yc != 1) { return -1; } if (mask_one_cnt == n / 2) { return n / 2 - getOneCnt(mask & 0xaaaaaaaa, 32); } else { return (n + 1) / 2 - getOneCnt(mask & 0x55555555, 32); } } }
int movesToChessboard(vector<vector<int>>& board) { int row_mask = 0, col_mask = 0; int n = board.size();
for (int i = 0; i < n; ++i) { row_mask |= (board[0][i] << i); col_mask |= (board[i][0] << i); } int reverse_row_mask = ((1 << n) - 1) ^ row_mask; int reverse_col_mask = ((1 << n) - 1) ^ col_mask; int row_cnt = 0, col_cnt = 0; for (int i = 0; i < n; ++i) { int curr_row_mask = 0; int curr_col_mask = 0;
for (int j = 0; j < n; ++j) { curr_row_mask |= (board[i][j] << j); curr_col_mask |= (board[j][i] << j); } if (curr_col_mask != col_mask && curr_col_mask != reverse_col_mask) { return -1; } else if (curr_col_mask == col_mask) { ++col_cnt; } if (curr_row_mask != row_mask && curr_row_mask != reverse_row_mask) { return -1; } else if (curr_row_mask == row_mask) { ++row_cnt; }
} int row_moves = getMoveCnt(row_mask, row_cnt, n); int col_moves = getMoveCnt(col_mask, col_cnt, n); return (row_moves == -1 || col_moves == -1) ? -1 : row_moves + col_moves; } };
|
分维度计算(java)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92
|
class Solution {
public int getOneCnt(int num) { int res = 0; while (num > 0) { res += num & 0x01; num >>= 1; } return res; }
public int getMoveCnt(int board_length, int mask, int cnt) { int mask_one_cnt = getOneCnt(mask); if (board_length % 2 == 0) { if ((board_length / 2) != mask_one_cnt || (board_length / 2) != cnt) { return -1; } int cnt0 = getOneCnt(mask & 0xaaaaaaaa); int cnt1 = getOneCnt(mask & 0x55555555); return cnt0 < cnt1 ? cnt0 : cnt1; } else { int ym = board_length - mask_one_cnt * 2, yc = board_length - cnt * 2; ym = ym < 0 ? -ym : ym; yc = yc < 0 ? -yc : yc; if (ym != 1 || yc != 1) return -1; if (mask_one_cnt == board_length / 2) { return mask_one_cnt - getOneCnt(mask & 0xaaaaaaaa); } else { return mask_one_cnt - getOneCnt(mask & 0x55555555); } } }
public int movesToChessboard(int[][] board) { int row_mask = 0, col_mask = 0; int n = board.length;
for (int i = n - 1; i > -1; --i) { row_mask |= (board[0][i] << i); col_mask |= (board[i][0] << i); }
int reverse_row_mask = ((1 << n) - 1) ^ row_mask; int reverse_col_mask = ((1 << n) - 1) ^ col_mask; int row_cnt = 0, col_cnt = 0;
for (int i = 0; i < n; ++i) { int curr_row_mask = 0; int curr_col_mask = 0; for (int j = n - 1; j > -1; --j) { curr_col_mask |= (board[j][i] << j); curr_row_mask |= (board[i][j] << j); }
if (reverse_col_mask != curr_col_mask && col_mask != curr_col_mask) { return -1; } if (reverse_row_mask != curr_row_mask && row_mask != curr_row_mask) { return -1; } if (col_mask == curr_col_mask) { ++col_cnt; } if (row_mask == curr_row_mask) { ++row_cnt; } }
int col_move_cnt = getMoveCnt(n, col_mask, col_cnt); int row_move_cnt = getMoveCnt(n, row_mask, row_cnt);
return col_move_cnt == -1 || row_move_cnt == -1 ? -1 : col_move_cnt + row_move_cnt; } }
|
分维度计算(python3)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68
|
class Solution:
def movesToChessboard(self, board: List[List[int]]) -> int: col_mask, row_mask = 0, 0 n = len(board) for i in range(n): row_mask |= (board[0][i] << i) col_mask |= (board[i][0] << i) reserve_row_mask = (1 << n) - 1 ^ row_mask reserve_col_mask = (1 << n) - 1 ^ col_mask row_cnt = col_cnt = 0 for i in range(n): curr_row_mask = curr_col_mask = 0 for j in range(n): curr_row_mask |= (board[i][j] << j) curr_col_mask |= (board[j][i] << j) if curr_row_mask != row_mask and curr_row_mask != reserve_row_mask: return -1 if curr_col_mask != col_mask and curr_col_mask != reserve_col_mask: return -1 if row_mask == curr_row_mask: row_cnt += 1 if col_mask == curr_col_mask: col_cnt += 1 def getOneCnt(num: int) -> int: res = 0 while num > 0: res += num & 0x01 num >>= 1 return res
def getMoveCnt(board_size: int, mask: int, cnt: int) -> int: mask_one_cnt = getOneCnt(mask) if board_size % 2 == 0: if mask_one_cnt != board_size // 2 or cnt != board_size // 2: return -1 cnt0 = mask_one_cnt - getOneCnt(mask & 0xaaaaaaaa) cnt1 = mask_one_cnt - getOneCnt(mask & 0x55555555) return min(cnt0, cnt1) else: ym = board_size - mask_one_cnt * 2 yc = board_size - cnt * 2 if ym < 0: ym = -ym if yc < 0: yc = -yc if ym != 1 or yc != 1: return -1 if board_size // 2 == mask_one_cnt: return mask_one_cnt - getOneCnt(mask & 0xaaaaaaaa) else: return mask_one_cnt - getOneCnt(mask & 0x55555555)
row_move_cnt = getMoveCnt(n, row_mask, row_cnt) col_move_cnt = getMoveCnt(n, col_mask, col_cnt)
return -1 if row_move_cnt == -1 or col_move_cnt == -1 else row_move_cnt + col_move_cnt
|