C/C++ LeetCode 5477. 排布二进制网格的最少交换次数

5477. 排布二进制网格的最少交换次数

  大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博主目前仅在CSDN中写博客,唯一博客更新的地址为:亓官劼的博客

本文原创为亓官劼,请大家支持原创,部分平台一直在恶意盗取博主的文章!!!


给你一个 n x n 的二进制网格 grid,每一次操作中,你可以选择网格的 相邻两行 进行交换。

一个符合要求的网格需要满足主对角线以上的格子全部都是 0

请你返回使网格满足要求的最少操作次数,如果无法使网格符合要求,请你返回 -1

主对角线指的是从 (1, 1)(n, n) 的这些格子。

示例 1:

C/C++ LeetCode 5477. 排布二进制网格的最少交换次数_第1张图片

输入:grid = [[0,0,1],[1,1,0],[1,0,0]]
输出:3

示例 2:

C/C++ LeetCode 5477. 排布二进制网格的最少交换次数_第2张图片

输入:grid = [[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0]]
输出:-1
解释:所有行都是一样的,交换相邻行无法使网格符合要求。

示例 3:

C/C++ LeetCode 5477. 排布二进制网格的最少交换次数_第3张图片

输入:grid = [[1,0,0],[1,1,0],[1,1,1]]
输出:0

提示:

  • n == grid.length
  • n == grid[i].length
  • 1 <= n <= 200
  • grid[i][j] 要么是 0 要么是 1

5477. 排布二进制网格的最少交换次数 题解

这题在比赛中没写完就结束了,卡死在了一个<=的边界。。。
这题的话和第二题一样,也是不能真的移动,而是要模拟,这里只需要我们移动行,使得我们的主对角线上方都是0,那么我们只需要使用一个数组来记录每一行右面连续0的个数,然后我们来使用这个数组来进行模拟即可。

class Solution {
public:
    int minSwaps(vector<vector<int>>& grid) {
        int n = grid.size();
        vector<int> zero_cnt(n);
        for (int i = 0; i < n; ++i) {
            int cnt = 0;
            for (int j = n - 1; j >= 0; --j) {
                if (grid[i][j] == 0) {
                    ++cnt;
                } else {
                    break;
                }
            }
            zero_cnt[i] = cnt;
        }
        int res = 0;
        for (int i = 0; i < n; ++i) {
            if (zero_cnt[i] >= n - i - 1) 
                continue;
            int j = i + 1;
            for (; j < n; ++j) {
                if (zero_cnt[j] >= n - i - 1) 
                    break;
            }
            if (j == n) return -1;
            res += j - i;
            rotate(zero_cnt.begin() + i, zero_cnt.begin() + j, zero_cnt.begin() + j + 1);
        }
        return res;
    }
};

你可能感兴趣的:(LeetCode)