栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

leetcode 782. Transform to Chessboard | 782. 变为棋盘(Java)

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

leetcode 782. Transform to Chessboard | 782. 变为棋盘(Java)

题目

https://leetcode.com/problems/transform-to-chessboard/

题解

没思路,看了答案。这道题没有套路,需要发现独特的规律,参考:

简单易懂的解法

【Python3】要么等于第一行 要么和第一行完全相反

代码是看着答案的思路,一句一句翻译过来的…详细原理见注释。

class Solution {
    public int movesToChessboard(int[][] board) {
        // 规则#1
        // 所有的"行",要么等于第0行,要么和第0行完全相反
        // 列也一样,但不需要去检查列,因为如果"行"合法,列必然合法,因此只需要判断"行"就行
        int N = board.length;
        boolean[] reverse = new boolean[N];
        for (int i = 1; i < N; i++) {
            reverse[i] = board[i][0] != board[0][0];
        }
        for (int i = 1; i < N; i++) {
            for (int j = 0; j < N; j++) {
                if (reverse[i] && board[i][j] == board[0][j]) return -1;
            }
        }
        // 规则#2
        // 每行的"1"的个数必须要么等于"0"的个数,要么相差1。因为规则#1已经通过,这次只要检查第0"行"就行。
        // 这次除了第0行,还需要检查第0列。
        int one = 0;
        for (int i = 0; i < N; i++) {
            if (board[0][i] == 1) one++;
        }
        if (Math.abs(N - 2 * one) > 1) return -1;
        one = 0;
        for (int i = 0; i < N; i++) {
            if (board[i][0] == 1) one++;
        }
        if (Math.abs(N - 2 * one) > 1) return -1;
        // 【计算交换次数】
        //     只需要计算第0行和第0列的交换次数就行,因为满足规则#1,所以剩下的行列肯定自动合法
        // 【首先,变换行】
        //     (1)假设左上角单元格是0,则可推知整行的每个单元格。计算实际与目标的diff个数,如果diff为偶数,则变化次数为差异点个数的一半
        //     (因为交换一次可以消除两个差异点)。如果diff为奇数,则无法变换为目标风格
        //     (2)假设左上角单元格是1。同上。
        //     (3)最后,选交换次数最小的作为行交换次数。
        // 【然后,变换列】
        //     列的变换算法和行没有任何差异,且行交换结果不影响列交换结果。
        // 【最后,行列交换次数相加】
        //     就是最终结果。
        int diffRow = 0;
        int swapRow;
        for (int i = 0; i < N; i++) { // 假设左上角为0,计算"行"交换个数
            if (i % 2 == 0) diffRow += board[0][i];
            else diffRow += (1 - board[0][i]);
        }
        if (diffRow % 2 == 0) {
            swapRow = diffRow / 2;
            if ((N - diffRow) % 2 == 0) swapRow = Math.min(swapRow, (N - diffRow) / 2); // N-diff是假设左上角为1的情况
        } else {
            swapRow = (N - diffRow) / 2;
        }

        // 行交换结果不影响列交换结果
        int diffCol = 0;
        int swapCol;
        for (int i = 0; i < N; i++) { // 假设左上角为0,计算"列"交换个数
            if (i % 2 == 0) diffCol += board[i][0];
            else diffCol += (1 - board[i][0]);
        }
        if (diffCol % 2 == 0) {
            swapCol = diffCol / 2;
            if ((N - diffCol) % 2 == 0) swapCol = Math.min(swapCol, (N - diffCol) / 2); // N-diff是假设左上角为1的情况
        } else {
            swapCol = (N - diffCol) / 2;
        }

        return swapRow + swapCol;
    }
}

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/271053.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号