大家好,我叫亓官劼(qí guān jié ),在CSDN中记录学习的点滴历程,时光荏苒,未来可期,加油~博主目前仅在CSDN中写博客,唯一博客更新的地址为:亓官劼的博客
本文原创为亓官劼,请大家支持原创,部分平台一直在恶意盗取博主的文章!!!
给你一个 n x n
的二进制网格 grid
,每一次操作中,你可以选择网格的 相邻两行 进行交换。
一个符合要求的网格需要满足主对角线以上的格子全部都是 0 。
请你返回使网格满足要求的最少操作次数,如果无法使网格符合要求,请你返回 -1 。
主对角线指的是从 (1, 1)
到 (n, n)
的这些格子。
示例 1:
输入:grid = [[0,0,1],[1,1,0],[1,0,0]]
输出:3
示例 2:
输入:grid = [[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0]]
输出:-1
解释:所有行都是一样的,交换相邻行无法使网格符合要求。
示例 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
。这题在比赛中没写完就结束了,卡死在了一个<=
的边界。。。
这题的话和第二题一样,也是不能真的移动,而是要模拟,这里只需要我们移动行,使得我们的主对角线上方都是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;
}
};