LeetCode每日一题(1568. Minimum Number of Days to Disconnect Island)

该文描述了一个算法问题,涉及到一个二进制网格,其中1表示陆地,0表示水。目标是在最少的天数内将网格断开连接,即形成超过一个岛屿。可以通过在一天内将一块陆地变为水来实现。提供的BFS解决方案用于计算当前网格中的岛屿数量。如果改变一块陆地后,岛屿数量少于原本的陆地数量,那么至少需要一天。若初始全为陆地,则至少需要两天。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

You are given an m x n binary grid grid where 1 represents land and 0 represents water. An island is a maximal 4-directionally (horizontal or vertical) connected group of 1’s.

The grid is said to be connected if we have exactly one island, otherwise is said disconnected.

In one day, we are allowed to change any single land cell (1) into a water cell (0).

Return the minimum number of days to disconnect the grid.

Example 1:

Input: grid = [[0,1,1,0],[0,1,1,0],[0,0,0,0]]
Output: 2

Explanation: We need at least 2 days to get a disconnected grid.
Change land grid[1][1] and grid[0][2] to water and get 2 disconnected island.

Example 2:

Input: grid = [[1,1]]
Output: 2

Explanation: Grid of full water is also disconnected ([[1,1]] -> [[0,0]]), 0 islands.

Constraints:

  • m == grid.length
  • n == grid[i].length
  • 1 <= m, n <= 30
  • grid[i][j] is either 0 or 1.

想了半天, 让别人一句话给点醒了, 任何形状的陆地, 最多将 2 块地变成水就可以实现不联通的状态。

我们只需要检查有没有变 0 或者 1 块就可以实现的情况就可以了

要注意的是全是水的情况也叫不连通



use std::collections::HashSet;

impl Solution {
    fn bfs(grid: &Vec<Vec<i32>>) -> i32 {
        let mut count = 0;
        let mut queue = Vec::new();
        let mut visited = HashSet::new();
        'outer: for r in 0..grid.len() {
            for c in 0..grid[0].len() {
                if grid[r][c] == 1 {
                    queue.push((r, c));
                    break 'outer;
                }
            }
        }
        while let Some((r, c)) = queue.pop() {
            if visited.contains(&(r, c)) {
                continue;
            }
            visited.insert((r, c));
            count += 1;
            if r > 0 && grid[r - 1][c] == 1 {
                queue.push((r - 1, c));
            }
            if r < grid.len() - 1 && grid[r + 1][c] == 1 {
                queue.push((r + 1, c));
            }
            if c > 0 && grid[r][c - 1] == 1 {
                queue.push((r, c - 1));
            }
            if c < grid[0].len() - 1 && grid[r][c + 1] == 1 {
                queue.push((r, c + 1));
            }
        }
        count
    }
    pub fn min_days(mut grid: Vec<Vec<i32>>) -> i32 {
        let mut num_of_land = 0;
        for r in 0..grid.len() {
            for c in 0..grid[0].len() {
                num_of_land += grid[r][c];
            }
        }
        if num_of_land == 0 {
            return 0;
        }
        let count = Solution::bfs(&grid);
        if count < num_of_land {
            return 0;
        }
        for r in 0..grid.len() {
            for c in 0..grid[0].len() {
                if grid[r][c] == 1 {
                    grid[r][c] = 0;
                    let count = Solution::bfs(&grid);
                    if count < num_of_land - 1 || count == 0 {
                        return 1;
                    }
                    grid[r][c] = 1;
                }
            }
        }
        2
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值