LeetCode 782 题解

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

题目大意:一个N*N的01序列,问最少通过交换行列多少次能使得0周围都是1,1周围都是0.

解题思路:

1.我的思路比较蠢

一开始的时候有很多坑,不过也是过了,思路大致思想就是贪心,从行入手比较相邻的两列,若相同则,往后找到一个不同的交换整个列,(但是此时有一个坑 ,例如这样 10100,可以发现如果按照我贪心的交换 会判断这种情况是错误的)为了应对这种情况,如果当此时判断的是最后一列,且前面的列没有进行过交换,则将最后一列交换到最开始。这样交换完成后,最后判断N*N的矩阵能否满足要求。

下面就要开始思考怎样计算最少的交换次数,这里有个坑,得考虑 N的奇偶,因为如果是偶数个N,可以使0开头也可以是1,这样会影响到交换次数。

2.优秀的解题思路

  • 考虑最终满足条件的情况,要么是010101... 要么是10101...这样的序列,也就是最终就两种情况,行的不同情况也就只有两种。当交换两列的时候,不会影响最终行的数目(即不管怎样交换列,行不同的情况就只有两种)
  • 可以确定当N为偶数时,01在每行里数量相同,N为奇数时,为N/2和N/2+1

以上可以确定是否能满足情况。

通过直接比较行和列与最终满足的情况不同位置的个数,就可以得到最少的交换次数。因为只要能组成满足题意的序列,则交换行列不会影响行和列不同序列的个数,所以调整一行或者一列满足01交错的序列,其他序列也能满足。

class Solution {
    public int movesToChessboard(int[][] board) {
        int n = board.length;
        for(int i=0;i(n+1)/2) return -1;
        if(col(n+1)/2) return -1;
        int res=0;
        if(n%2==0)
        {
            res+=Math.min(cntrow,n-cntrow);
            res+=Math.min(cntcol,n-cntcol);
        }
        else
        {
            if(cntrow%2==1)
                cntrow = n-cntrow;
            if(cntcol%2==1)
                cntcol = n-cntcol;
            res=cntrow+cntcol;
        }
        return res/2;
    }
}


我的代码有点长

class Solution {
    public int movesToChessboard(int[][] board) {
        int n = board.length;
        int cnt = 0;
        //看列
        int tmp;
        int pre;
        for(int i=0;i

782 Transform to Chessboard

你可能感兴趣的:(leetcode)