Given an n x n binary grid, in one step you can choose two adjacent rows of the grid and swap them.
A grid is said to be valid if all the cells above the main diagonal are zeros.
Return the minimum number of steps needed to make the grid valid, or -1 if the grid cannot be valid.
The main diagonal of a grid is the diagonal that starts at cell (1, 1) and ends at cell (n, n).
Example 1:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-qwPPWF7m-1630939550654)(https://assets.leetcode.com/uploads/2020/07/28/fw.jpg)]
Input: grid = [[0,0,1],[1,1,0],[1,0,0]]
Output: 3
Example 2:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-09872adR-1630939550657)(https://assets.leetcode.com/uploads/2020/07/16/e2.jpg)]
Input: grid = [[0,1,1,0],[0,1,1,0],[0,1,1,0],[0,1,1,0]]
Output: -1
Explanation: All rows are similar, swaps have no effect on the grid.
Example 3:
[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-l7UGNlEq-1630939550658)(https://assets.leetcode.com/uploads/2020/07/16/e3.jpg)]
Input: grid = [[1,0,0],[1,1,0],[1,1,1]]
Output: 0
Constraints:
- n == grid.length
- n == grid[i].length
- 1 <= n <= 200
- grid[i][j] is 0 or 1
我们把每行最后一个1的位置拿出来,这个位置其实就是该行应该所能在的最小index。举个例子
[
[0,0,1],
[1,1,0],
[1,0,0]
]
第1行最后一个1的index是2, 所以第1行的最小的合法index是2
第2行最后一个1的index是1, 所以第2行的最小的合法index是1
第2行最后一个1的index是0, 所以第2行的最小的合法index是0
在这里我们要考虑全是0的情况, 这种情况我们要把index设为-1
然后我们把这些index收集起来就得到一个数组, 上面例子收集起来如下:
min_indices = [2, 1, 0]
剩下的就是移动计步了
简单来说就是min_indices[i] > i的这种都需要移动,向后找j, j > i, min_indices[j] <= min_indices[i]就可以进行交换了, 因为只能相邻的行移动, 所以这样需要j-i步
代码实现(Rust):
impl Solution {
pub fn min_swaps(grid: Vec<Vec<i32>>) -> i32 {
let mut min_indices: Vec<i32> = grid.into_iter().map(|l| {
l.into_iter().rposition(|v| v == 1).map(|i| i as i32).unwrap_or(-1)
}).collect();
println!("{:?}", min_indices);
let mut indices = min_indices.clone();
indices.sort();
for (i, v) in indices.into_iter().enumerate() {
if (i as i32) < v {
return -1;
}
}
let mut steps = 0;
'outer: loop {
for i in 0..min_indices.len() {
if (i as i32) < min_indices[i] {
for j in i+1..min_indices.len() {
if min_indices[j] <= (i as i32) {
let idx = min_indices.remove(j);
min_indices.insert(i, idx);
steps += (j - i) as i32;
continue 'outer;
}
}
}
}
break
}
steps
}
}