在程序考虑bfs算法的时候,需要考虑两个问题:
1、标记: 对于遍历过的节点,应该将它标记,防止重复遍历
2、需要一个队列来存储每一轮遍历得到的节点
深度优先遍历:
class Solution {
private int[][] directions = {{-1,0},{0,1},{1,0},{0,-1}} ; // 定义方向数组,分别表示上右下左 横向第一个参数是0,纵向第二个参数是0
private int row,col; //定义总的行数和列数
public int maxAreaOfIsland(int[][] grid){
if(grid==null || grid.length==0) return 0;
row = grid.length;
col = grid[0].length;
int maxArea = 0;
for(int i =0;i<row;i++){
for (int j =0;j<col;j++){
maxArea = Math.max(maxArea,dfs(grid,i,j));
}
}
return maxArea;
}
// dfs深度优先遍历
private int dfs(int[][] grid,int r ,int c){
// 判断当前传入坐标是否越界或者是水域
if(r<0 || r>=row ||c<0 ||c>=col || grid[r][c] ==0){
return 0; //满足任意一种情况就说明不是岛屿或者不在图内
}
grid[r][c] =0; //已经访问过的岛屿也修改为0,避免重复访问
int area =1 ; // 每个岛屿的面积都是1,固定大小的
for(int[] d :directions){
//在四个方向上进行深度优先探寻,探寻完毕再访问上一层累加 d[0] 横坐标
area += dfs(grid,r+d[0],c+d[1]);
}
return area;
}
}
class Solution {
private int[][] directions ={{-1,0},{0,1},{1,0},{0,-1}};
private int m,n;
public int numIslands(char[][] grid) {
m=grid.length;
n=grid[0].length;
int areaCount =0;
for(int i=0;i<m;i++){
for (int j =0;j<n;++j)
{ //是岛屿就进行深度优先遍历
if(grid[i][j] == '1'){
dfs(grid,i,j);
areaCount++; //数量+1
}
}
}
return areaCount;
}
private void dfs(char[][] grid ,int i,int j){ //并不需要返回值,因为只是用来遍历
if(i<0 || i>=m || j<0 || j>=n || grid[i][j] != '1'){
//越界或者是水域的时候不进行dfs操作
return ;
}
grid[i][j] ='0'; //表示这个岛屿访问过了
for(int[] d :directions){ //进行深度优先遍历
dfs(grid,i+d[0],j+d[1]);
}
}
}
class Solution {
// 就是寻找在非对称轴上1的个数,且这个矩阵关于主轴对称,只需要看一半 因为(i,j)=1 与(j,i) = 1是一个意思
// 矩阵是一个方阵
public int findCircleNum(int[][] isConnected) {
int n= isConnected.length;
// 访问过的城市无需再次访问 true访问过,false没有访问
boolean[] visited = new boolean[n];
int provices=0;
for(int i =0;i<n;i++){
//如果当前城市i没有访问过,就去执行dfs,找到所有和i相连的城市
if(!visited[i]){
dfs(isConnected,i,visited);
// 一趟dfs结束后,所有与i相连的城市都找到
provices++;
}
}
return provices;
}
private void dfs(int[][] isConnected,int i,boolean[] visited){
visited[i]=true; //初始访问标记为true
for(int j=0;j<isConnected.length;j++){
// 如果城市i和城市j相连,并且城市j还未访问过,就以j为新的节点继续递归找到与j相连的其他城市
if(isConnected[i][j]==1 && !visited[j]){
dfs(isConnected,j,visited);
}
}
}
}
class Solution {
/**
思路:先用dfs,把所有四边边缘上的o以及与其相连的里面的o改成T,剩下的就是里面被x包围
的o,
*/
private int[][] directions = {{-1,0},{0,1},{1,0},{0,-1}};
private int row,col;
public void solve(char[][] board) {
row = board.length;
col = board[0].length;
// 首先按行进行dfs,把图的左边缘与右边缘上所有的o以及与其相连的o全部改成T;
for(int i=0;i<row;i++){
dfs(board,i,0);
dfs(board,i,col-1);
}
// 上下的边缘
for(int j =0;j<col;j++){
dfs(board,0,j);
dfs(board,row-1,j);
}
// 最后遍历一遍图把所有的T恢复成o,把所有的o改成x
for(int i=0;i<row;i++){
for(int j=0;j<col;j++){
if(board[i][j]=='T'){ // 换回去
board[i][j]='O';
}else if(board[i][j]=='O'){ // 按题目要求改成o
board[i][j]='X';
}
}
}
}
//深度优先遍历
private void dfs(char[][] board,int r,int c){
// 判断是否越界
if(r<0 || r>=row || c<0|| c>=col || board[r][c] !='O'){return;}
board[r][c] ='T'; // 四周边缘上的变成T
for(int[] d:directions){
dfs(board,r+d[0],c+d[1]);
}
}
}