• LeetCode-695. 岛屿的最大面积


    题目描述

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

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

    示例 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]]
    

    对于上面这个给定矩阵应返回 6。注意答案不应该是11,因为岛屿只能包含水平或垂直的四个方向的‘1’。

    示例 2:

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

    对于上面这个给定的矩阵, 返回 0。

    注意: 给定的矩阵grid 的长度和宽度都不超过 50。

    解题思路

    这是一道典型的搜索问题,最早入门学习算法看的书《啊哈,算法》中对类似问题有非常清晰简单的解析。在这里也给出深度优先(DFS)和广度优先(BFS)两种解决方法。

    DFS

    深度优先搜索实现的核心是借助递归,沿着某一条路径一路往下走到不能再走为止。

    class SolutionDFS {
    public:
        int maxAreaOfIsland(vector<vector<int>>& grid) 
        {
            if(grid.empty())
                return 0;
    
            int res = 0;
            
            // 定义标记数组
            vector<vector<bool>> vecMark(grid.size(),vector<bool>(grid[0].size(),false));
    
            // 定义搜索边界
            int mostDeep = grid.size();
            int mostLeft = grid[0].size();
    
            //开始搜索
            for(int i = 0;i < mostDeep;i++)
            {
                for(int j = 0;j < mostLeft;j++)
                {
                    if(vecMark[i][j] == true)
                        continue;
                    int temp = dfs(grid, i, j, vecMark);
                    res = max(res, temp);
                }
            }
    
            return res;
        }
    private:
        int dfs(vector<vector<int>>& grid, int x, int y,vector<vector<bool>>& mark)
        {
            if(x >=  grid.size() || y >= grid[0].size() || x < 0 || y < 0)
                return 0;
                
            if(mark[x][y] == true)
                return 0;
            if(grid[x][y] == 0)
                return 0;
            
            // 对于点[x,y]搜索上下左右4个点是否是岛屿
            // 即[x-1,y],[x+1,y],[x,y-1],[x,y+1]
            // 对于已经搜索过的点要进行标记
            
            mark[x][y] = true;
    
            return 1 + dfs(grid, x+1, y, mark) + dfs(grid, x-1, y, mark) + dfs(grid, x, y+1, mark) + dfs(grid, x, y-1, mark);
        }
    };
    

    BFS

    广度优先搜索实现的核心是借助栈来进行层层遍历。

    class SolutionBFS{
    public:
        int maxAreaOfIsland(vector<vector<int>>& grid) 
        {
            if(grid.empty())
                return 0;
    
            int res = 0;
    
            // 定义标记数组
            vector<vector<bool>> vecMark(grid.size(),vector<bool>(grid[0].size(),false));
    
            // 定义搜索边界
            int mostDeep = grid.size();
            int mostLeft = grid[0].size();
    
            //开始搜索
            for(int i = 0;i < mostDeep;i++)
            {
                for(int j = 0;j < mostLeft;j++)
                {
                    if(vecMark[i][j] == true)
                        continue;
    
                    if(grid[i][j] == 0)
                        continue;
    
                    int itempArea = 0;
                    //定义临时栈
                    stack<pair<int,int>> stackTemp;
                    stackTemp.push(make_pair(i,j));
                    vecMark[i][j] = true;
                    
                    while(!stackTemp.empty())
                    {  
                        itempArea++;
                        
                        pair<int,int> curPoint = stackTemp.top();
                        stackTemp.pop();
                        
                        int x = curPoint.first;
                        int y = curPoint.second;
    
                        if(x-1 >= 0 && grid[x-1][y] == 1 && vecMark[x-1][y] == false)
                        {
                            stackTemp.push(make_pair(x-1, y));
                            vecMark[x-1][y] = true;
                        }    
                        
                        if(x+1 < mostDeep && grid[x+1][y] == 1 && vecMark[x+1][y] == false)
                        {
                            stackTemp.push(make_pair(x+1, y)); 
                            vecMark[x+1][y] = true;                    
                        }
                            
                        if(y-1 >= 0 && grid[x][y-1] == 1 && vecMark[x][y-1] == false) 
                        {
                            stackTemp.push(make_pair(x, y-1));
                            vecMark[x][y-1] = true;
                        }
                        
                        if(y+1 < mostLeft && grid[x][y+1] == 1 && vecMark[x][y+1] == false)
                        {    
                            stackTemp.push(make_pair(x, y+1));   
                            vecMark[x][y+1] = true;
                        }
                    }
                    res = max(res, itempArea);
                }
            }        
    
            return res;
        }
    };
    
  • 相关阅读:
    vector容器(一)
    螺旋数组实现
    zigzag数组实现
    HDU 1496
    HDU 1381 Crazy Search
    什么叫软核,固核,硬核?
    “杜拉拉思维模式”之六:小组面试提升术
    硬件工程师电路设计必须紧记的十大要点
    面试的“群殴”宝典
    三段式状态机 [CPLD/FPGA]
  • 原文地址:https://www.cnblogs.com/BlueskyRedsea/p/9348338.html
Copyright © 2020-2023  润新知