Weekly Contest 71 leetcode 782. Transform to Chessboard
7587 ワード
An N x N
What is the minimum number of moves to transform the board into a "chessboard"- a board where no
Note:
この問題の構想は以下の通りである:(この問題は少し難易度が高いので、私がこの時間を忙しくしてから、ゆっくり見てください)
An observation is that, in a valid ChessBoard, any rectangle inside the board with corner
Since the swap process does not break this property, for a given board to be valid, this property must hold. A corollary is that given a row,any other row must be identical to it or be its inverse(逆).For example if there is a row
With this observation, we only need to consider the first column when we're swapping rows to match the ChessBoard condition. That is,it suffies(それで十分)to find the minimum row swap to make the first column be
Similarly, it suffies to consider the first row when swapping columns.
Now the problem becomes solvable, with the following steps: Check if the given board satisfy the validness property defined above. Find minimum row swap to make the first column valid. If not possible, return -1. Find minimum column swap to make the first row valid. If not possible, return -1. Return the sum of step 2 and 3.
この問題solutions:https://leetcode.com/problems/transform-to-chessboard/solution/
Approach #1: Dimension Independence [Accepted]
Intuition
After a swap of columns, two rows that were the same stay the same, and two rows that were different stay different. Since the final state of a chessboard has only two different kinds of rows, there must have originally been only two different kinds of rows.
Furthermore, these rows must have had half zeros and half ones, (except when the length is odd, where there could be an extra zero or one), and one row must be the opposite (
Similarly, the above is true for columns.
Now, because a row move followed by a column move is the same as a column move followed by a row move, we can assume all the row moves happen first, then all the column moves. (Note: it is not true that a row move followed by another row move is the same as those moves backwards.)
Since there are only two kinds of rows, we want the minimum number of moves to make them alternating; and similarly for columns. This reduces to a one dimensional problem, where we have an array like
Algorithm
For each set of rows (and columns respectively), make sure there are only 2 kinds of lines in the right quantities that are opposites of each other.
Then, for each possible ideal transformation of that line, find the minimum number of swaps to convert that line to it's ideal and add it to the answer. For example,
In Java, we use integers to represent the rows as binary numbers. We check the number of differences with
Complexity Analysis
Time Complexity: O(N^2)O(N2), where NN is the number of rows (and columns) in
Space Complexity: O(N)O(N), the space used by
board
contains only 0
s and 1
s. In each move, you can swap any 2 rows with each other, or any 2 columns with each other. What is the minimum number of moves to transform the board into a "chessboard"- a board where no
0
s and no 1
s are 4-directionally adjacent? If the task is impossible, return -1. Examples:
Input: board = [[0,1,1,0],[0,1,1,0],[1,0,0,1],[1,0,0,1]]
Output: 2
Explanation:
One potential sequence of moves is shown below, from left to right:
0110 1010 1010
0110 --> 1010 --> 0101
1001 0101 1010
1001 0101 0101
The first move swaps the first and second column.
The second move swaps the second and third row.
Input: board = [[0, 1], [1, 0]]
Output: 0
Explanation:
Also note that the board with 0 in the top left corner,
01
10
is also a valid chessboard.
Input: board = [[1, 0], [1, 0]]
Output: -1
Explanation:
No matter what sequence of moves you make, you cannot end with a valid chessboard.
Note:
board
will have the same number of rows and columns, a number in the range [2, 30]
. board[i][j]
will be only 0
s or 1
s. この問題の構想は以下の通りである:(この問題は少し難易度が高いので、私がこの時間を忙しくしてから、ゆっくり見てください)
An observation is that, in a valid ChessBoard, any rectangle inside the board with corner
NW, NE, SW, SE
(NW here means north-west) must satisfy the validness property: (NW xor NE) == (SW xor SE)
, Since the swap process does not break this property, for a given board to be valid, this property must hold. A corollary is that given a row,any other row must be identical to it or be its inverse(逆).For example if there is a row
01010011
in the board, any other row must be either 01010011
or 10101100
. With this observation, we only need to consider the first column when we're swapping rows to match the ChessBoard condition. That is,it suffies(それで十分)to find the minimum row swap to make the first column be
010101...^T
or 101010...^T
.(here ^T
means transpose.)Similarly, it suffies to consider the first row when swapping columns.
Now the problem becomes solvable, with the following steps:
この問題solutions:https://leetcode.com/problems/transform-to-chessboard/solution/
Approach #1: Dimension Independence [Accepted]
Intuition
After a swap of columns, two rows that were the same stay the same, and two rows that were different stay different. Since the final state of a chessboard has only two different kinds of rows, there must have originally been only two different kinds of rows.
Furthermore, these rows must have had half zeros and half ones, (except when the length is odd, where there could be an extra zero or one), and one row must be the opposite (
0
changed to 1
and vice versa) of the other row. This is because moves do not change these properties either. Similarly, the above is true for columns.
Now, because a row move followed by a column move is the same as a column move followed by a row move, we can assume all the row moves happen first, then all the column moves. (Note: it is not true that a row move followed by another row move is the same as those moves backwards.)
Since there are only two kinds of rows, we want the minimum number of moves to make them alternating; and similarly for columns. This reduces to a one dimensional problem, where we have an array like
[0, 1, 1, 1, 0, 0]
and we want to know the least cost to make it [0, 1, 0, 1, 0, 1]
or [1, 0, 1, 0, 1, 0]
. Algorithm
For each set of rows (and columns respectively), make sure there are only 2 kinds of lines in the right quantities that are opposites of each other.
Then, for each possible ideal transformation of that line, find the minimum number of swaps to convert that line to it's ideal and add it to the answer. For example,
[0, 1, 1, 1, 0, 0]
has two ideals [0, 1, 0, 1, 0, 1]
or [1, 0, 1, 0, 1, 0]
; but [0, 1, 1, 1, 0]
only has one ideal [1, 0, 1, 0, 1]
. In Java, we use integers to represent the rows as binary numbers. We check the number of differences with
[1, 0, 1, 0, 1, 0, ...]
by xoring with 0b010101010101.....01 = 0x55555555
. To make sure we don't add extra large powers of 2, we also bitwise-AND by 0b00...0011...11
where there are N
ones in this mask. class Solution {
public int movesToChessboard(int[][] board) {
int N = board.length;
// count[code] = v, where code is an integer
// that represents the row in binary, and v
// is the number of occurrences of that row
Map count = new HashMap();
for (int[] row: board) {
int code = 0;
for (int x: row)
code = 2 * code + x;
count.put(code, count.getOrDefault(code, 0) + 1);
}
int k1 = analyzeCount(count, N);
if (k1 == -1) return -1;
// count[code], as before except with columns
count = new HashMap();
for (int c = 0; c < N; ++c) {
int code = 0;
for (int r = 0; r < N; ++r)
code = 2 * code + board[r][c];
count.put(code, count.getOrDefault(code, 0) + 1);
}
int k2 = analyzeCount(count, N);
return k2 >= 0 ? k1 + k2 : -1;
}
public int analyzeCount(Map count, int N) {
// Return -1 if count is invalid
// Otherwise, return number of swaps required
if (count.size() != 2) return -1;
List keys = new ArrayList(count.keySet());
int k1 = keys.get(0), k2 = keys.get(1);
// If lines aren't in the right quantity
if (!(count.get(k1) == N/2 && count.get(k2) == (N+1)/2) &&
!(count.get(k2) == N/2 && count.get(k1) == (N+1)/2))
return -1;
// If lines aren't opposite
if ((k1 ^ k2) != (1< N) // ones start
cand = Math.min(cand, Integer.bitCount(k1 ^ 0x55555555 & Nones) / 2);
return cand;
}
}
Complexity Analysis
Time Complexity: O(N^2)O(N2), where NN is the number of rows (and columns) in
board
. Space Complexity: O(N)O(N), the space used by
count
.