An N x N 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.
题目理解:
给定一个方阵,问能否通过行列变换,将其变为一个棋盘:在行和列上,0和1交替出现
解题思路:
观察一个棋盘,可以发现,任意奇数列之间交换,或者任意偶数列之间交换之后,棋盘还是一个棋盘。也就是说,只要第一行保证0和1是交替出现的,那么列就不用在调整了,只调整行就可以变成棋盘。对于行来说,道理是一样的。
也就是说,如果将第一行和第一列调整为棋盘形式,再判断是否整个方阵是不是棋盘,如果不是,那么方阵就不能调整为棋盘。
但是也有一些特殊情况,导致无法调整为棋盘,因此可以尝试先调整一下行的顺序,将每一行放到第一行,尝试调整,如果能得到棋盘就返回。
至于题目中问到的最小步数,只需要判断第一行中需要调整的0的个数和第一列中需要调整的0的个数即可
class Solution {
public boolean judge(int[][] board){
int len = board.length;
for(int i = 0; i < len; i++){
for(int j = 0; j < len; j++){
if(i > 0 && board[i - 1][j] == board[i][j])
return false;
if(j > 0 && board[i][j - 1] == board[i][j])
return false;
}
}
return true;
}
public int change(boolean flag, int[][] board){
int res = 0;
int len = board.length;
if(flag){//one first
//change column
for(int i = 0; i < len; i++){
if(i % 2 == 0 && board[0][i] != 1){
int j = 0;
while(j < len){
if(board[0][j] == 1 && j % 2 == 1)
break;
j++;
}
if(j >= len)
break;
for(int row = 0; row < len; row++){
int temp = board[row][i];
board[row][i] = board[row][j];
board[row][j] = temp;
}
res++;
}
}
//change row
for(int i = 0; i < len; i++){
if(i % 2 == 0 && board[i][0] != 1){
int j = 0;
while(j < len){
if(board[j][0] == 1 && j % 2 == 1)
break;
j++;
}
if(j >= len)
break;
for(int col = 0; col < len; col++){
int temp = board[i][col];
board[i][col] = board[j][col];
board[j][col] = temp;
}
res++;
}
}
//change column
for(int i = 0; i < len; i++){
if(i % 2 == 0 && board[0][i] != 1){
int j = 0;
while(j < len){
if(board[0][j] == 1 && j % 2 == 1)
break;
j++;
}
if(j >= len)
break;
for(int row = 0; row < len; row++){
int temp = board[row][i];
board[row][i] = board[row][j];
board[row][j] = temp;
}
res++;
}
}
}
else{
//change column
for(int i = 0; i < len; i++){
if(i % 2 == 0 && board[0][i] != 0){
int j = 0;
while(j < len){
if(board[0][j] == 0 && j % 2 == 1)
break;
j++;
}
//System.out.println(i + " " + j);
if(j >= len)
break;
for(int row = 0; row < len; row++){
int temp = board[row][i];
board[row][i] = board[row][j];
board[row][j] = temp;
}
res++;
}
}
//change row
for(int i = 0; i < len; i++){
if(i % 2 == 0 && board[i][0] != 0){
int j = 0;
while(j < len){
if(board[j][0] == 0 && j % 2 == 1)
break;
j++;
}
if(j >= len)
break;
for(int col = 0; col < len; col++){
int temp = board[i][col];
board[i][col] = board[j][col];
board[j][col] = temp;
}
res++;
}
}
//change column
for(int i = 0; i < len; i++){
if(i % 2 == 0 && board[0][i] != 0){
int j = 0;
while(j < len){
if(board[0][j] == 0 && j % 2 == 1)
break;
j++;
}
//System.out.println(i + " " + j);
if(j >= len)
break;
for(int row = 0; row < len; row++){
int temp = board[row][i];
board[row][i] = board[row][j];
board[row][j] = temp;
}
res++;
}
}
}
if(!judge(board))
return -1;
return res;
}
public int movesToChessboard(int[][] board) {
int len = board.length;
int[][] copy = new int[len][len];
int res = -1;
for(int k = 0; k < len; k++){
for(int i = 0; i < len; i++){
for(int j = 0; j < len; j++){
if(i == 0){
copy[i][j] = board[k][j];
}
else if(i == k){
copy[i][j] = board[0][j];
}
else
copy[i][j] = board[i][j];
}
}
int cur = change(true, copy);
if(k != 0 && cur != -1)
cur++;
if(res == -1 || res > cur && cur != -1)
res = cur;
for(int i = 0; i < len; i++){
for(int j = 0; j < len; j++){
if(i == 0){
copy[i][j] = board[k][j];
}
else if(i == k){
copy[i][j] = board[0][j];
}
else
copy[i][j] = board[i][j];
}
}
cur = change(false, copy);
if(k != 0 && cur != -1)
cur++;
if(res == -1 || res > cur && cur != -1)
res = cur;
}
return res;
}
}