代码随想录-广度优先搜索理论基础及相关习题

广度优先搜索理论基础

广搜的搜索方式就适合于解决两个点之间的最短路径问题。因为广搜是从起点出发,以起始点为中心一圈一圈进行搜索,一旦遇到终点,记录之前走过的节点就是一条最短路。
广搜是一圈一圈的遍历方式,如下图:
代码随想录-广度优先搜索理论基础及相关习题_第1张图片
遍历可以是用队列,还是用栈,甚至用数组实现。以下是使用队列实现的模板:

//方向数组
 //上(0,1)
 //右(1,0)
 //左(-1,0)
 //下(0,-1)
public int dir[][]={{0,1},{1,0},{-1,0},{0,-1}};
//用于记录是否走过
public boolean[][] visited;
public void bfs(char[][] grid,int x,int y){
        //使用栈实现节点遍历
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{x,y});
        visited[x][y]=true;
        while(!queue.isEmpty()){
            int [] node=queue.poll();
            //像四个方向移动
            int nodex=node[0];
            int nodey=node[1];
            for(int i=0;i<4;i++){
                int nextx=nodex+dir[i][0];
                int nexty=nodey+dir[i][1];
                //边界判断
                if(nextx<0||nextx>=grid.length||nexty<0||nexty>=grid[0].length){
                    continue;
                }
                //入栈并标记
                if(visited[nextx][nexty]==false){
                    queue.offer(new int[]{nextx,nexty});
                    visited[nextx][nexty]=true;
                }
            }
        }
    }

岛屿数量

广搜版

class Solution {
    //上(0,1)
    //右(1,0)
    //左(-1,0)
    //下(0,-1)
    public int dir[][]={{0,1},{1,0},{-1,0},{0,-1}};
    public boolean[][] visited;
    public int numIslands(char[][] grid) {
        //标记是否走过
        visited=new boolean[grid.length][grid[0].length];
        int res=0;
        for(int p=0;p<grid.length;p++){
            for(int q=0;q<grid[0].length;q++){
                if(grid[p][q]=='1'&&!visited[p][q]){
                   oneoflands(grid,p,q);
                   res++; 
                }
            }
        }
        return res;
    }
    public void oneoflands(char[][] grid,int x,int y){
        //使用栈实现节点遍历
        Queue<int[]> queue = new LinkedList<>();
        queue.offer(new int[]{x,y});
        visited[x][y]=true;
        while(!queue.isEmpty()){
            int [] node=queue.poll();
            //像四个方向移动
            int nodex=node[0];
            int nodey=node[1];
            for(int i=0;i<4;i++){
                int nextx=nodex+dir[i][0];
                int nexty=nodey+dir[i][1];
                //边界判断
                if(nextx<0||nextx>=grid.length||nexty<0||nexty>=grid[0].length){
                    continue;
                }
                //入栈
                if(grid[nextx][nexty]=='1'&&visited[nextx][nexty]==false){
                    queue.offer(new int[]{nextx,nexty});
                    visited[nextx][nexty]=true;
                }
            }
        }
    }
}

深搜版

class Solution {
    boolean[][] visited;
    int dir[][] = {
        {0, 1}, //right
        {1, 0}, //down
        {-1, 0}, //up
        {0, -1} //left
    };
    public int numIslands(char[][] grid) {
        int count = 0;
        visited = new boolean[grid.length][grid[0].length];

        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid[0].length; j++){
                if(visited[i][j] == false && grid[i][j] == '1'){
                    count++;
                    dfs(grid, i, j);
                }
            }
        }
        return count;
    }

    private void dfs(char[][]grid, int x, int y){
        if(visited[x][y] == true || grid[x][y] == '0')
            return;
	    
        visited[x][y] = true;
	
        for(int i = 0; i < 4; i++){
            int nextX = x + dir[i][0];
            int nextY = y + dir[i][1];
            if(nextX < 0 || nextY < 0 || nextX >= grid.length || nextY >= grid[0].length)
                continue;
            //当前节点满足条件 使用递归标记当前节点的周围节点
            dfs(grid, nextX, nextY);
        }
    }
}

你可能感兴趣的:(代码随想录,宽度优先,算法)