leetcode 经典宽搜BFS深搜DFS题目(思路、方法、code)

leetcode 经典宽搜BFS深搜DFS题目(思路、方法、code)

BFS和DFS的经典应用就是在树和图中的遍历。

地图的搜索问题通常都可以用BFS和DFS解决,下面题目非常典型,并且很多题目类似,自己如果能够独立完成基本就掌握了BFS和DFS以及地图的遍历问题。

200. 岛屿数量

给你一个由 ‘1’(陆地)和 ‘0’(水)组成的的二维网格,请你计算网格中岛屿的数量。

岛屿总是被水包围,并且每座岛屿只能由水平方向或竖直方向上相邻的陆地连接形成。

此外,你可以假设该网格的四条边均被水包围。

示例 1:
输入:
11110
11010
11000
00000
输出: 1
    
示例 2:
输入:
11000
11000
00100
00011
输出: 3
解释: 每座岛屿只能由水平和/或竖直方向上相邻的陆地连接而成。

分析:求解该问题,实际上就是要找多少个陆地区域,因此采用BFS、DFS两种方法均可遍历。核心思路在于,当发现一个陆地,需要将其上下左右四个方向所有可以延展到的陆地都要加入其中(可以直接将这些陆地变为海洋即可),根据此,遍历所有区域还要注意的是,这个题目的输入是 char 不是 int

BFS方法

通过一个队列,每次找到一个陆地后,进行BFS搜索,将该陆地所在的整体陆地地区全部更新为海洋。(需要注意的是,这里每次push进队列时,就直接将该位置赋值为海洋,否则会push进很多重复节点)

class Solution {
   
public:
    int numIslands(vector< vector<char> >& grid) 
	{
   
		if(grid.size()==0) return 0;
		int result=0;
		for(int i=0;i<grid.size();i++)
		for(int j=0;j<grid[0].size();j++)
		{
   
			if(grid[i][j]=='1')  //找到一个陆地就要把相连的全部变为水 
			{
      result++;
				queue< pair<int,int> > Q;
				Q.push(make_pair(i,j)); //调用make_pair使(i,j)转化为pair
                grid[i][j]='0'; //将该地区置为0
				while(!Q.empty())
				{
   
					pair<int,int> top=Q.front();
					Q.pop();
					//接着把上下左右四个方向的陆地加进去 
                    //注意push时候就要将其改为'0',要不然重复太多
					if(top.first-1>=0&&grid[top.first-1][top.second]=='1')	 
                    {
      grid[top.first-1][top.second]='0';
                        Q.push(make_pair(top.first-1,top.second));
                    }
					if(top.second-1>=0&&grid[top.first][top.second-1]=='1')	 
                    {
      grid[top.first][top.second-1]='0';
                        Q.push(make_pair(top.first,top.second-1));
                    }
					if(top.first+1<grid.size()&&grid[top.first+1][top.second]=='1') 
                    {
   
                        grid[top.first+1][top.second]='0';
                        Q.push(make_pair(top.first+1,top.second));
                    }
				  if(top.second+1<grid[0].size()&&grid[top.first][top.second+1]=='1') 
                    {
   
                        grid[top.first][top.second+1]='0';
                        Q.push(make_pair(top.first,top.second+1));
                    }
				} 
			}
		}
        return result;
		
    }
};

DFS方法:

采用DFS递归深搜即可,思路与BFS一致,遍历方法不同而已。

class Solution {
   
    void DFS(vector<vector<char>> &grid,int cur_i,int cur_j)
    {
   
        if(cur_i<0||cur_i==grid.size()||cur_j<0||cur_j==grid[0].size()||grid[cur_i][cur_j]=='0') return;
        grid[cur_i][cur_j]='0';  //将其标记为海洋
        int di[4]={
   0,0,1,-1};
        int dj[4]={
   1,-1,0,0};       //方向数组
        for(int index=0;index<4;index++) //四个方向遍历
        {
   
            DFS(grid,cur_i+di[index],cur_j+dj[index]);  //找到一个陆地就直接继续深入搜索
        }
        return;
    }
public:
    int numIslands(vector<vector<char>>& grid) {
   
        int ans=0;
        for(int i=0;i<grid.size();i++)
        {
   
            for(int j=0;j<grid[0].size();j++)
            {
   
                if(grid[i][j]=='1')
                {
   
                    ans++;
                    DFS(grid,i,j);
                } 
            }
        }
        return ans;
    }

};
127. 单词接龙

给定两个单词(beginWord 和 endWord)和一个字典,找到从 beginWord 到 endWord 的最短转换序列的长度。转换需遵循如下规则:每次转换只能改变一个字母。转换过程中的中间单词必须是字典中的单词。
说明:如果不存在这样的转换序列,返回 0。所有单词具有相同的长度。所有单词只由小写字母组成。
字典中不存在重复的单词。你可以假设 beginWord 和 endWord 是非空的,且二者不相同。

示例 1:
输入:
beginWord = "hit",
endWord = "cog",
wordList = ["hot","dot","dog","lot","log","cog"]

输出: 5
解释: 一个最短转换序列是 "hit" -> "hot" -> "dot" -> "dog" -> "cog",
     返回它的长度 5。
     
示例 2:
输入:
beginWord = "hit"
endWord = "cog"
wordList = ["hot","dot","dog","lot","log"]

输出: 0
解释: endWord "cog" 不在字典中,所以无法进行转换。

分析:(这个mid难度有点hard)

将单词之间的转换,理解为一张图,即如果两个单词之间可以转换(相差一个字母),就说明这两个单词之间

  • 0
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值