岛屿的最大面积--DFS(附搜索全家桶)

0x01.问题

给定一个包含了一些 0 和 1的非空二维数组 grid , 一个 岛屿 是由四个方向 (水平或垂直) 的 1 (代表土地) 构成的组合。你可以假设二维矩阵的四个边缘都被水包围着。

找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为0。)

输入示例:

[[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]]

输出示例:

6

解释:最大的岛屿面积为6

C++函数形式为:   int maxAreaOfIsland(vector<vector<int>>& grid) 

 0x02.分析问题

要想得到一个小岛屿的面积,我们第一感觉肯定就是搜索,怎么搜索呢,遍历每一个结点,如果是1,就开始搜索,直到把这个结点所在的岛屿全部遍历到,然后可以得到这个岛屿的面积,具体的搜索过程,可以使用DFS,没有路了就回来,不断的回溯。

为了知道我们哪些地方是已经遍历到了的,我们的第一想法肯定就是设置一个标志数组,访问记为1,这种想法确实可以,但没有必要。

为什么呢?因为我们之前已经遍历到了的话,已经参与计数了,那么这个点就失去了它存在的意义,我们就可以假设它不存在,如何假设,有点是1,没有是0,把1变成0就可以了,这样还可以省下一个二维数组的空间,这种方法也叫 沉岛思想。

0x03.解决代码--DFS(递归)

class Solution {
public:
    int DFS(int x,int y,vector<vector<int>>& grid){
        if(x<0||y<0||x>=grid.size()||y>=grid[0].size()||grid[x][y]==0){
            return 0;
        }
        int num=1;
        grid[x][y]=0;
        num+=DFS(x+1,y,grid);
        num+=DFS(x,y+1,grid);
        num+=DFS(x-1,y,grid);
        num+=DFS(x,y-1,grid);
        return num;
    }
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int maxSize=0;
        for(int i=0;i<grid.size();i++){
            for(int j=0;j<grid[0].size();j++){
                if(grid[i][j]==1){
                    maxSize=max(maxSize,DFS(i,j,grid));
                }
            }
        }
        return maxSize;
    }
};

0x04.解决代码--DFS(栈)

思路就是访问结点访问时,我们将对围绕它四个方向进行探索,找到还未访问的结点,加入到栈中。

只要栈不为空,就从栈中取出一个元素并访问。

这样就可以达到递归同样的效果。

class Solution {
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int maxSize = 0;
        for (int i = 0; i != grid.size(); ++i){
            for (int j = 0; j != grid[0].size(); ++j) {
                if (grid[i][j] == 1) {
                        int cur = 0;
                        stack<int> stacki;
                        stack<int> stackj;
                        stacki.push(i);
                        stackj.push(j);
                        while (!stacki.empty()) {
                            int x = stacki.top(), y = stackj.top();
                            stacki.pop();
                            stackj.pop();
                            if (x < 0 || y < 0 || x == grid.size() || y == grid[0].size() || grid[x][y] != 1)
                                continue;
                            ++cur;
                            grid[x][y] = 0;
                            int dx[4] = { 0, 0, 1, -1 };
                            int dy[4] = { 1, -1, 0, 0 };
                            for (int index = 0; index != 4; ++index) {
                                int next_x = x + dx[index], next_y = y + dy[index];
                                stacki.push(next_x);
                                stackj.push(next_y);
                            }
                        }
                   maxSize = max(maxSize, cur);
                }
            }
        return maxSize;
    }
};

0x05.解决代码--BFS(广度,队列)

思路是每次从队首取出结点,并将接下来想要遍历的土地放在队尾,就实现了广度的搜索。
 

class Solution {
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int maxSize = 0;
        for (int i = 0; i != grid.size(); ++i)
            for (int j = 0; j != grid[0].size(); ++j) {
                if (grid[i][j] == 1) {
                    int cur = 0;
                    queue<int> queuei;
                    queue<int> queuej;
                    queuei.push(i);
                    queuej.push(j);
                    while (!queuei.empty()) {
                        int x = queuei.front(), y = queuej.front();
                        queuei.pop();
                        queuej.pop();
                        if (x < 0 || y < 0 || x == grid.size() || y == grid[0].size() || grid[x][y] != 1)
                            continue;
                        ++cur;
                        grid[x][y] = 0;
                        int dx[4] = { 0, 0, 1, -1 };
                        int dy[4] = { 1, -1, 0, 0 };
                        for (int index = 0; index != 4; ++index) {
                            int next_x = x + dx[index], next_y = y + dy[index];
                            queuei.push(next_x);
                            queuej.push(next_y);
                        }
                    }
                    maxSize = max(maxSize, cur);
                }
            }
        return maxSize;
    }
};

ATFWUS  --Writing  By 2020--03--15

  • 32
    点赞
  • 45
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

ATFWUS

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值