题目链接:LeetCode 1536. 排布二进制网格的最少交换次数
题意:
给你一个 n x n 的二进制网格 grid,每一次操作中,你可以选择网格的 相邻两行 进行交换。
一个符合要求的网格需要满足主对角线以上的格子全部都是 0 。
请你返回使网格满足要求的最少操作次数,如果无法使网格符合要求,请你返回 -1 。
主对角线指的是从 (1, 1) 到 (n, n) 的这些格子。
解题思路:
首先将每行从后往前遍历,找零的个数,放置在数组中
如果满足那一行,就不必交换
class Solution {
/**
* @param Integer[][] $grid
* @return Integer
*/
function minSwaps($grid) {
$n = count($grid);
$res = array();
for($i = 0; $i < $n; $i++) {
$cnt = 0;
for($j = $n-1; $j >= 0; $j--) {
if($grid[$i][$j] == 0) { // 每行从后往前有多少个0
$cnt++;
} else {
break;
}
}
array_push($res, $cnt);
}
$ans = 0;
for($i = 0; $i < $n-1; $i++) {
if($res[$i] >= $n-$i-1) continue; // 大于等于就不必交换
for($j = $i; $j < $n; $j++) {
if($res[$j] >= $n-$i-1) {
break;
}
}
if($j == $n) { // 如果找到最后一行也没有找到符合的行,返回-1
return -1;
}
for( ; $j > $i; $j--) { // 进行交换
$t = $res[$j];
$res[$j] = $res[$j-1];
$res[$j-1] = $t;
$ans++;
}
}
return $ans;
}
}