28、【栈和队列】岛屿问题(C++版)——DFS和BFS解法

题目描述

在这里插入图片描述
在这里插入图片描述

题目分析

题中的目标是求由1组成的岛屿有几个,先观察便界条件:当某个1的四周均为0时,或到达边界时,即为一个岛屿。可以使用BFS和DFS两种方式进行搜索,被搜索过的岛屿标记为“2”,不标记为“0”便于区分。

参考文章:岛屿数量

参考文章:岛屿数量(dfs+并查集详解)

参考文章:200. 岛屿数量(DFS+BFS)

DFS解法

DFS为深度优先遍历算法:

首先,确定好开始起点后,按一定规则顺序从四周选择方向,当选择的方向符合某一条件后,就依照该方向进行延伸选择结点,将选择的结点再为新一轮起点依照之前定义的规则顺序再从四周选择方向,以此类推,直到到达边界条件后,退回一步,按照上述选择四周的规则选择下一个方向,直至完成全图的扫描。

class Solution {
public:
    int numIslands(vector<vector<char>>& grid) {
		if(grid.size() == 0)	return 0;
		int row = grid.size(), col = grid[0].size(), count = 0;
		for(int i = 0; i < row; i++){
			for(int j = 0; j < col; j++){
				if(grid[i][j] == '1'){
					count++;
					DFS(grid, i, j);
				}
			}
		}
		return	count;
    }

	void DFS(vector<vector<char>>& grid, int i, int j){
	//注意一定要先判断inArea才能再grid[i][j]是否为1
		if(inArea(i, j, grid.size(), grid[0].size()) && grid[i][j] == '1'){ 
			grid[i][j] = '2';
            DFS(grid, i, j+1);
            DFS(grid, i+1, j);
            DFS(grid, i, j-1);
			DFS(grid, i-1, j);	
		}
	}

	bool inArea(int i, int j, int row, int col){
		return (i>=0)&&(i<row)&&(j>=0)&&(j<col);
	}
};

时间复杂度为O(M * N),空间复杂度为O(M * N),其中M为行数,N为列数。

BFS解法

BFS为广度优先搜索算法:

首先,确定开始起点,然后按照一定规则顺序先遍历起点四周的各点,被遍历到的点若符合某一条件,在起点的四周遍历完后,将会依次按上述规则顺序对之前被遍历的符合条件的点的四周进行依次遍历。以此类推,直至扫描完全图后为止。

class Solution{
public:
	int numIslands(vector<vector<char>>& grid){
		if(grid.size() == 0)	return 0;
		int count = 0;
		for(int i = 0; i < grid.size(); i++){
			for(int j = 0; j < grid[0].size(); j++){
				if(grid[i][j] == '1'){
					count++;
					grid[i][j] = '2';
					BFS(grid, i, j);
				}
		    }
	    }
        return count;
    }
	void BFS(vector<vector<char>>& grid, int i, int j){
		queue<pair<int,int>> q;
		q.push({i, j});
		while(!q.empty()){
			auto cur = q.front();	q.pop();
			int x = cur.first, y = cur.second;
			if(y + 1 < grid[0].size() && grid[x][y+1] == '1'){
				q.push({x, y+1});
				grid[x][y+1] = '2';
			}
			if(x + 1 < grid.size() && grid[x+1][y] == '1'){
				q.push({x+1, y});
				grid[x+1][y] = '2';
			}			
			if(y - 1 >= 0 && grid[x][y-1] == '1'){
				q.push({x, y-1});
				grid[x][y-1] = '2';
			}			
			if(x - 1 >= 0 && grid[x-1][y] == '1'){
				q.push({x-1, y});
				grid[x-1][y] = '2';
			}
		}
	}
};

时间复杂度为O(M * N),空间复杂度为O(min(M, N)),其中M为行数,N为列数。在最坏情况下,整个网格均为陆地,队列的大小可以达到 min⁡(M,N)。

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 2
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

辰阳星宇

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

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

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

打赏作者

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

抵扣说明:

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

余额充值