LeetCode每日一题(Minimum Swaps to Arrange a Binary Grid)

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
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值