搜索算法 深度优先搜索 695. Max Area of Island

本文探讨了一种解决二维二进制矩阵中最大岛屿面积问题的高效算法。通过改进的深度优先搜索和邻接方向更新策略,减少了空间使用并优化了搜索过程。核心内容包括利用栈实现的深度优先遍历,以及技巧性的坐标移动。

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

You are given an m x n binary matrix grid. 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.
The area of an island is the number of cells with a value 1 in the island.
Return the maximum area of an island in grid. If there is no island, return 0.
Example 1:
Input: grid = [[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]]
Output: 6
Explanation: The answer is not 11, because the island must be connected 4-directionally.
Example 2:
Input: grid = [[0,0,0,0,0,0,0,0]]
Output: 0
Constraints:
m == grid.length
n == grid[i].length
1 <= m, n <= 50
grid[i][j] is either 0 or 1.

直接做,写的挺丑陋但过了,时间复杂度On,空间复杂度On

class Solution {
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int max_area = 0;
        vector<vector<bool>> visit(grid.size(),vector<bool>(grid[0].size(),false));
        for(int i = 0; i < grid.size(); i++){
            for(int j = 0; j < grid[0].size(); j++){
                int area = 0;
                if(grid[i][j] == 1 && !visit[i][j]){
                    stack<vector<int>> s;
                    s.push(vector<int>{i,j});
                    visit[i][j] = true;
                    area ++;
                    while(!s.empty()){
                        int ii = s.top()[0];
                        int jj = s.top()[1];
                        s.pop();
                        if(ii-1 >= 0 && grid[ii-1][jj] == 1 && !visit[ii-1][jj]){
                            s.push(vector<int>{ii-1,jj});
                            visit[ii-1][jj] = true;
                            area ++;
                        }
                        if(ii+1 < grid.size() && grid[ii+1][jj] == 1 && !visit[ii+1][jj]){
                            s.push(vector<int>{ii+1,jj});
                            visit[ii+1][jj] = true;
                            area ++;
                        }
                        if(jj-1 >= 0 && grid[ii][jj-1] == 1 && !visit[ii][jj-1]){
                            s.push(vector<int>{ii,jj-1});
                            visit[ii][jj-1] = true;
                            area ++;
                        }
                        if(jj+1 < grid[0].size() && grid[ii][jj+1] == 1 && !visit[ii][jj+1]){
                            s.push(vector<int>{ii,jj+1});
                            visit[ii][jj+1] = true;
                            area ++;
                        }
                    }
                }
                max_area = max(max_area,area);
            }
        }
        return max_area;
    }
};

其实这里没必要用一个数组记录访没访问过,每次经过把1改成0就行了。
再就是上下左右搜索有一个小技巧,就是用数组{{-1,0},{1,0},{0,-1},{0,1}}分别加上坐标
或者{-1,0,1,0,-1} 每次取i和i+1加到坐标的i和j上。

class Solution {
public:
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int max_area = 0;
        vector<int> dir{-1,0,1,0,-1};
        for(int i = 0; i < grid.size(); i++){
            for(int j = 0; j < grid[0].size(); j++){
                int area = 0;
                if(grid[i][j]){
                    stack<pair<int,int>> s;
                    s.push({i,j});
                    grid[i][j] = 0;
                    area ++;
                    while(!s.empty()){
                        // int r = s.top().first;
                        // int c = s.top().second;
                        auto [r,c] = s.top();
                        s.pop();
                        for(int k = 0; k < dir.size()-1; k++){
                            int ii = r + dir[k];
                            int jj = c + dir[k+1];
                            if(ii >= 0 && ii < grid.size() && jj >= 0 && jj < grid[0].size() && grid[ii][jj]){
                                s.push({ii,jj});
                                grid[ii][jj] = 0;
                                area ++;
                            }
                        }
                    }  
                }
                max_area = max(max_area,area);
            }
        }
        return max_area;
    }
};

auto [r,c] = s.top();不太懂这个auto的数据类型。
尝试用递归写一下

class Solution {
public:
    vector<int> dir{-1,0,1,0,-1};
    int dfs(vector<vector<int>>& grid, int i, int j){
        int area = 1;
        grid[i][j] = 0;
        for(int k = 0; k < dir.size()-1; k++){
            int x = i + dir[k], y = j + dir[k+1];
            if(x >= 0 && x < grid.size() && y >= 0 && y < grid[0].size() && grid[x][y]){
                area += dfs(grid,x,y);
            }
        }
        return area;
    }
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        int max_area = 0;
        for(int i = 0; i < grid.size(); i++){
            for(int j = 0; j < grid[0].size(); j++){
                if(grid[i][j]){
                    max_area = max(max_area, dfs(grid,i,j));
                }
            }
        }
        return max_area;
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值