[LeetCode]695. Max Area of Island 解题报告(C++)

[LeetCode]695. Max Area of Island 解题报告(C++)

题目描述

Given a non-empty 2D array grid of 0’s and 1’s, an island is a group of 1’s (representing land) connected 4-directionally (horizontal or vertical.) You may assume all four edges of the grid are surrounded by water.

Find the maximum area of an island in the given 2D array. (If there is no island, the maximum area is 0.)

Example 1:

[[0,0,1,0,0,0,0,1,0,0,0,0,0],
 [0,0,0,0,0,0,0,1,1,1,0,0,0],
 [0,1,1,0,1,0,0,0,0,0,0,0,0],
 [0,1,0,0,1,1,0,0,1,0,1,0,0],
 [0,1,0,0,1,1,0,0,1,1,1,0,0],
 [0,0,0,0,0,0,0,0,0,0,1,0,0],
 [0,0,0,0,0,0,0,1,1,1,0,0,0],
 [0,0,0,0,0,0,0,1,1,0,0,0,0]]

Given the above grid, return

6

. Note the answer is not 11, because the island must be connected 4-directionally.

Example 2:

[[0,0,0,0,0,0,0,0]]

Given the above grid, return

0

Note: The length of each dimension in the given grid does not exceed 50.

题目大意

  • 给定一个二维数组,找到最大连通的1的个数. 水平和垂直方向

解题思路

方法一:

  • 递归的方式进行搜索
  • 遍历 grid ,当遇到1的点,调用递归函数.
  • 在递归函数中:
    • 先判断 i,j是否越界.
    • 还有判断 grid[i][j]是否为1.(没有使用visited数组,直接在原数组上做更改.).遍历过的标记为-1.
    • 若是没有 visit过.则cnt++; 并更新 res;
    • 然后再对相邻四个位置分别调用 递归函数.
代码实现:
class Solution1{
public:
    // 注意这种方向的写法.用于遍历很好用
    vector<vector<int>> dirs{ { 0,-1 },{ -1,0 },{ 0,1 },{ 1,0 } };

    int maxAreaOfIsland(vector<vector<int>>& grid) {

        int row = grid.size();
        int col = grid[0].size();

        int res = 0;

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {

                // 判断是否为1,是的话,可以开始递归遍历
                // 否则跳过,遍历一下.
                if (grid[i][j] != 1) continue;

                int cnt = 0; // 初始化为0
                helper(grid, i, j, cnt, res);

            }
        }

        return res;
    }

    void helper(vector < vector<int>> &grid, int i, int j, int &cnt, int &res) {

        int row = grid.size();
        int col = grid[0].size();

        // 越界判断与条件不符合的判断
        if (i < 0 || i >= row || j < 0 || j >= col || grid[i][j] <= 0) {
            return;
        }

        // 更新
        res = max(res, ++cnt);
        // 其实算是更改visit[][]
        grid[i][j] = -1;

        // 递归遍历
        for (auto dir : dirs) {
            helper(grid, i + dir[0], j + dir[1], cnt, res);
        }

    }

};

方法2:

  • 非递归遍历, 迭代方法
  • 深度优先遍历
  • 利用 queue 来辅助运算
    • 为什么是队列呢.
    • 因为 要遍历个这个点附近的四个点的周围.而且按深度优先遍历.
代码实现:
class Solution2{
public:
    vector<vector<int>> dirs{ { 0,-1 },{ -1,0 },{ 0,1 },{ 1,0 } };
    int maxAreaOfIsland(vector<vector<int>>& grid) {

        int row = grid.size();
        int col = grid[0].size();

        int res = 0;

        for (int i = 0; i < row; i++) {
            for (int j = 0; j < col; j++) {

                if(grid[i][j]!=1) continue;

                // 重新开始计数
                int cnt = 0;

                // 如何初始化?
                // {i,j} 起始点入队
                queue<pair<int, int>> q{ { { i,j } } };

                // visited,置为-1;
                grid[i][j] = -1;

                while (!q.empty()){
                    // 取到点,出队.
                    auto t = q.front();
                    q.pop();
                    // 更新
                    res = max(++cnt, res);
                    //遍历
                    for (auto dir : dirs) {
                        // 注意边界判断
                        int x = t.first + dir[0], y = t.second + dir[1];
                        if (x < 0 || x >= row || y < 0 || y >= col || grid[x][y] <= 0) {
                            continue;
                        }

                        // visited,置为-1;入队
                        grid[x][y] = -1;
                        q.push({ x, y });
                    }
                }
            }
        }
        return res;
    }
};

小结

  • 递归用的方向的写法 vector<vector<int>> dirs{ { 0,-1 },{ -1,0 },{ 0,1 },{ 1,0 } };
  • 深度优先遍历用的 队列 queue .
  • visited[][] 数组的使用. (本题在自身数组上进行修改.其实本事就是visited[][] 数组)
  • 边界的判断. if (i < 0 || i >= row || j < 0 || j >= col || grid[i][j] <= 0)
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值