LeetCode: Transform to Chessboard

An N x N board contains only 0s and 1s. 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 0s and no 1s are 4-directionally adjacent? If the task is impossible, return -1.

class Solution {
public:
    int movesToChessboard(vector<vector<int>>& board) {
        int N = board.size();
        for(int i=0;ifor(int j=0;jif((board[0][0]^board[i][0]^board[0][j]^board[i][j])) return -1; 
                // 递推验证棋盘具有仅含两种列和行的性质。
                // 从两行两列开始,新棋盘在旧棋盘的基础上添加四个角中的两个,如果两个重叠的角相等,则新添加的角也必然相等,反之亦然。
                // 新棋盘中由于添加角而扩展的旧边将保证相等或相反,其他行或列被包含在其他旧棋盘的扩展边中,所有行或列都将被递推地验证这一性质。
        int rowSum = 0,colSum = 0;
        int rowSwap = 0,colSwap = 0;
        for(int i=0;i0];
            colSum += board[0][i];
            rowSwap += i%2 == board[i][0]; // 标记board首列不属于abab模式的行数目为 N-rowSwap 或 rowSwap
            colSwap += i%2 == board[0][i]; // 标记board首行不属于abab模式的列数目为 N-colSwap 或 colSwap
        }

        if(N/2 > rowSum || (N+1)/2 < rowSum) return -1;
        if(N/2 > colSum || (N+1)/2 < colSum) return -1;

        if(N&1){
            if(rowSwap&1) rowSwap = N-rowSwap; // 由于不符合abab模式的行或列总是成对出现,所以值为偶数就是实际需要交换的行或列数目
            if(colSwap&1) colSwap = N-colSwap;
        }else{
            rowSwap = min(N-rowSwap,rowSwap);  // 由于不符合abab模式的行或列数目不可能大于N/2,所以值更小的就是实际需要交换的行或列数目
            colSwap = min(N-colSwap,colSwap);
        }

        return (rowSwap+colSwap)/2; // 行或列交换次数=需要交换的行或列数目/2

    }
};

你可能感兴趣的:(LeetCode)