LeetCode每日一题(1992. Find All Groups of Farmland)

You are given a 0-indexed m x n binary matrix land where a 0 represents a hectare of forested land and a 1 represents a hectare of farmland.

To keep the land organized, there are designated rectangular areas of hectares that consist entirely of farmland. These rectangular areas are called groups. No two groups are adjacent, meaning farmland in one group is not four-directionally adjacent to another farmland in a different group.

land can be represented by a coordinate system where the top left corner of land is (0, 0) and the bottom right corner of land is (m-1, n-1). Find the coordinates of the top left and bottom right corner of each group of farmland. A group of farmland with a top left corner at (r1, c1) and a bottom right corner at (r2, c2) is represented by the 4-length array [r1, c1, r2, c2].

Return a 2D array containing the 4-length arrays described above for each group of farmland in land. If there are no groups of farmland, return an empty array. You may return the answer in any order.

Example 1:

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

Explanation:
The first group has a top left corner at land[0][0] and a bottom right corner at land[0][0].
The second group has a top left corner at land[1][1] and a bottom right corner at land[2][2].

Example 2:

Input: land = [[1,1],[1,1]]
Output: [[0,0,1,1]]

Explanation:
The first group has a top left corner at land[0][0] and a bottom right corner at land[1][1].

Example 3:

Input: land = [[0]]
Output: []

Explanation:
There are no groups of farmland.

Constraints:

  • m == land.length
  • n == land[i].length
  • 1 <= m, n <= 300
  • land consists of only 0’s and 1’s.
  • Groups of farmland are rectangular in shape.

一开始把题目理解错了, 复杂度直接上升了一个数量级, 后来又仔细读了读题目, 觉得题目里说的 land 可能只包含合法的 group, 题目的目的是让你找出这些 group,而不是找出的同时还要检查是否合法。后来证明这样想是对的。

既然 land 中都是合法的 group, 那我们只需要按顺序从上到下从左到右的检查每一个单元格,如果该单元格为 1 且左侧或者上方的单元格也为 1,则可以认定该单元格是当前情况的所在 group 的最右下角,但是怎么确定当前的单元格属于哪个 group 呢?我们可以用一个自增的序列号来为每个单元格进行标号,因为初始状态下,land 中都是 0 和 1,所以我们的序列号从 2 开始, 如果一个为 1 的单元格左侧和上方有相邻的为 1 的单元格,那该单元格的序列号就要与它的左侧或者上方的单元格的序列号相同,因为他们都是同一个 group 的,如果没有相邻为 1 的单元格,那该单元格就需要赋值为当前序列号的值。这样我们就可以保证相邻且为 1 的单元格的序列号是相等的, 这样我们就可以以 group 的序列号为 key 来保存和更新 group 的开始单元格和结束单元格



use std::collections::HashMap;

impl Solution {
    pub fn find_farmland(mut land: Vec<Vec<i32>>) -> Vec<Vec<i32>> {
        let mut seq = 1;
        let mut ans = HashMap::new();
        for i in 0..land.len() {
            for j in 0..land[0].len() {
                seq += 1;
                if land[i][j] == 0 {
                    continue;
                }
                if i > 0 && land[i - 1][j] > 1 {
                    let group: &mut Vec<i32> = ans.get_mut(&land[i - 1][j]).unwrap();
                    group[2] = i as i32;
                    group[3] = j as i32;
                    land[i][j] = land[i - 1][j];
                    continue;
                }
                if j > 0 && land[i][j - 1] > 1 {
                    let group: &mut Vec<i32> = ans.get_mut(&land[i][j - 1]).unwrap();
                    group[2] = i as i32;
                    group[3] = j as i32;
                    land[i][j] = land[i][j - 1];
                    continue;
                }
                land[i][j] = seq;
                ans.insert(seq, vec![i as i32, j as i32, i as i32, j as i32]);
            }
        }
        ans.into_values().collect()
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值