算法专题十六:BFS

BFS解决 FloodFill算法

图像渲染

733. 图像渲染 - 力扣(LeetCode)

class Solution {
    int dx[]={0,0,1,-1};
    int dy[]={1,-1,0,0};
    public int[][] floodFill(int[][] image, int sr, int sc, int color) {
        int prev=image[sr][sc];
        if(prev==color){
            return image;
        }
        Queue<int[]> q=new LinkedList<>();
        q.add(new int[]{sr,sc});
        image[sr][sc]=color;
        int m=image.length;
        int n=image[0].length;
        while(!q.isEmpty()){
            int[] t=q.poll();
            int a=t[0];
            int b=t[1];
            for(int i=0;i<4;i++){
                int x=a+dx[i];
                int y=b+dy[i];
                if(x>=0 && x<m && y>=0 && y<n && image[x][y]==prev){
                    q.add(new int[]{x,y});
                    image[x][y]=color;
                }
            }
        }
        return image;
    }
}

岛屿数量

200. 岛屿数量 - 力扣(LeetCode)

class Solution {
    int m;
    int n;
    int[] dx={0,0,1,-1};
    int[] dy={1,-1,0,0};
    boolean[][] check=new boolean[301][301];
    public int numIslands(char[][] grid) {
        m=grid.length;
        n=grid[0].length;
        int ret=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]=='1' && check[i][j]!=true){
                    ret++;
                    bds(grid,i,j);
                }
            }
        }
        return ret;

    }
    public void bds(char[][] grid,int i,int j){
        Queue<int[]> q=new LinkedList<>();
        q.add(new int[]{i,j});
        check[i][j]=true;
        while(!q.isEmpty()){
            int[] t=q.poll();
            int a=t[0];
            int b=t[1];
            for(int k=0;k<4;k++){
                int x=a+dx[k];
                int y=b+dy[k];
                if(x>=0 && x<m && y>=0 && y<n && check[x][y]==false && grid[x][y]=='1'){
                    q.add(new int[]{x,y});
                    check[x][y]=true;
                }

            }
        }
    }
}

岛屿的最大面积

695. 岛屿的最大面积 - 力扣(LeetCode)

class Solution {
    int[] dx={0,0,1,-1};
    int[] dy={1,-1,0,0};
    int m;
    int n;
    boolean[][] check=new boolean[51][51];
    public int maxAreaOfIsland(int[][] grid) {
        m=grid.length;
        n=grid[0].length;
        int count=0;
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]==1 && check[i][j]!=true){
                    count = Math.max(count, bfs(grid, i, j));
                }
            }
        }
        return count;
    }

    public int bfs(int[][] grid,int i,int j){
        Queue<int[]> q=new LinkedList<>();
        q.add(new int[]{i,j});
        check[i][j]=true;
        int c=1;
        while(!q.isEmpty()){
            int[] t=q.poll();
            int a=t[0];
            int b=t[1];
            for(int k=0;k<4;k++){
                int x=a+dx[k];
                int y=b+dy[k];
                if(x>=0 && x<m && y>=0 && y<n && check[x][y]==false && grid[x][y]==1){
                    q.add(new int[]{x,y});
                    check[x][y]=true;
                    c++;
                }
            }
        }
        return c;

    }
}

被围绕的区域

130. 被围绕的区域 - 力扣(LeetCode)

class Solution {
    int[] dx={0,0,1,-1};
    int[] dy={1,-1,0,0};
    int m;
    int n;
    public void solve(char[][] board) {
        m=board.length;
        n=board[0].length;
        for(int j=0;j<n;j++){
            if(board[0][j]=='O'){
                bfs(board,0,j);
            }
            if(board[m-1][j]=='O'){
                bfs(board,m-1,j);
            }
        }

        for(int i=0;i<m;i++){
            if(board[i][0]=='O'){
                bfs(board,i,0);
            }
            if(board[i][n-1]=='O'){
                bfs(board,i,n-1);
            }
        }

        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(board[i][j]=='O'){
                    board[i][j]='X';
                }
                if(board[i][j]=='?'){
                    board[i][j]='O';
                }
            }
        }
    }

    public void bfs(char[][] board,int i,int j){
        Queue<int[]> q=new LinkedList<>();
        q.add(new int[]{i,j});
        board[i][j]='?';
        while(!q.isEmpty()){
            int[] t=q.poll();
            int a=t[0];
            int b=t[1];
            for(int k=0;k<4;k++){
                int x=a+dx[k];
                int y=b+dy[k];
                if(x>=0 && x<m && y>=0 && y<n && board[x][y]=='O'){
                    board[x][y]='?';
                    q.add(new int[]{x,y});
                }
            }
        }
    }
}

BFS 解决最短路径问题

迷宫中离入口最近的出口

1926. 迷宫中离入口最近的出口 - 力扣(LeetCode)

class Solution {
    int[] dx={0,0,-1,1};
    int[] dy={1,-1,0,0};
    public int nearestExit(char[][] maze, int[] entrance) {
        int m=maze.length;
        int n=maze[0].length;
        boolean[][] check=new boolean[m][n];
        Queue<int[]> q=new LinkedList<>();
        q.add(new int[]{entrance[0],entrance[1]});
        check[entrance[0]][entrance[1]]=true;
        int ret=0;
        while(!q.isEmpty()){
            ret++;
            int size=q.size();
            for(int i=0;i<size;i++){
                int[] t=q.poll();
                int a=t[0];
                int b=t[1];
                for(int k=0;k<4;k++){
                    int x=a+dx[k];
                    int y=b+dy[k];
                    if(x>=0 && x<m && y>=0 && y<n && maze[x][y]=='.' && check[x][y]==false){
                        if(x==0 || x==m-1 || y==0 || y==n-1){
                            return ret;
                        }
                        q.add(new int[]{x,y});
                        check[x][y]=true;
                    }
                }
            }
        }
        return -1;
    }
}

最小基因变化

433. 最小基因变化 - 力扣(LeetCode)

class Solution {
    public int minMutation(String startGene, String endGene, String[] bank) {
        Set<String> se=new HashSet<>();//存入已经搜索过的基因
        Set<String> hash=new HashSet<>();//存入基因库中的基因
        for(String s:bank){
            hash.add(s);
        }
        char[] ch={'A','C','G','T'};
        if(startGene.equals(endGene)){
            return 0;
        }
        if(!hash.contains(endGene)){
            return -1;
        }

        Queue<String> q=new LinkedList<>();
        q.add(startGene);
        se.add(startGene);
        int step=0;
        while(!q.isEmpty()){
            step++;
            int size=q.size();
            while(size--!=0){
                String m=q.poll();
                for(int i=0;i<8;i++){
                    char[] tmp=m.toCharArray();
                    for(int j=0;j<4;j++){
                        tmp[i]=ch[j];
                        String next=new String(tmp);
                        if(hash.contains(next) && !se.contains(next)){
                            if(next.equals(endGene)){
                                return step;
                            }
                            q.add(next);
                            se.add(next);
                        }
                    }
                }
            }
        }
        return -1;
        
    }
}

单词接龙

127. 单词接龙 - 力扣(LeetCode)

class Solution {
    public int ladderLength(String beginWord, String endWord, List<String> wordList) {
        Set<String> se=new HashSet<>();
        Set<String> hash=new HashSet<>();
        int s=beginWord.length();
        se.add(beginWord);
        for(String n:wordList){
            hash.add(n);
        }
        if(!hash.contains(endWord)){
            return 0;
        }
        if(beginWord.equals(endWord)){
            return 1;
        }
        Queue<String> q=new LinkedList<>();
        q.add(beginWord);
        int step=1;
        while(!q.isEmpty()){
            step++;
            int size=q.size();
            while(size--!=0){
                String m=q.poll();
                for(int i=0;i<s;i++){
                    char[] tem=m.toCharArray();
                    for(char ch='a';ch<='z';ch++ ){
                        tem[i]=ch;
                        String next=new String(tem);
                        if(hash.contains(next) && !se.contains(next)){
                            if(next.equals(endWord)){
                                return step;
                            }
                            q.add(next);
                            se.add(next);
                        }
                    }
                }
            }
        }
            return 0;

    }
}

为高尔夫比赛砍树

675. 为高尔夫比赛砍树 - 力扣(LeetCode)

在砍树的过程中必须是按照从小到大的顺序进行砍树

class Solution {
    int m;
    int n;
    public int cutOffTree(List<List<Integer>> forest) {
        m=forest.size();
        n=forest.get(0).size();
        List<int[]> tree=new ArrayList<>();
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(forest.get(i).get(j)>1){
                    tree.add(new int[]{i,j});
                }
            }
        }
        Collections.sort(tree,(a,b)->{
            return forest.get(a[0]).get(a[1])-forest.get(b[0]).get(b[1]);
        });
        int ax=0;
        int bx=0;
        int ret=0;
        for(int[] next:tree){
            int a=next[0];
            int b=next[1];
            int step=bfs(forest,ax,bx,a,b);
            if(step==-1){
                return -1;
            }
            ret+=step;
            ax=a;
            bx=b;    
        }
        return ret;
    }
    int[] am={0,0,1,-1};
    int[] bm={1,-1,0,0};


    public int bfs(List<List<Integer>> forest,int ax,int bx,int a,int b){
        if(ax==a && bx==b){
            return 0;
        }
        Queue<int[]> q=new LinkedList<>();
        boolean[][] check=new boolean[m][n];
        int count=0;
        q.add(new int[]{ax,bx});
        check[ax][bx]=true;
        while(!q.isEmpty()){
            count++;
            
            int size=q.size();
            while(size--!=0){
                int[] t=q.poll();
                int at=t[0];
                int bt=t[1];
                for(int i=0;i<4;i++){
                    int x=at+am[i];
                    int y=bt+bm[i];
                    if(x>=0 && x<m && y>=0 && y<n &&forest.get(x).get(y)!=0 &&check[x][y]!=true){
                        if(x==a && y==b){
                            return count;
                        }
                        q.add(new int[]{x,y});
                        check[x][y]=true;
                    }
                }
            }
        }
        return -1;
    }
}

多源BFS

01矩阵

542. 01 矩阵 - 力扣(LeetCode)

class Solution {
    int[] dx={0,0,-1,1};
    int[] dy={1,-1,0,0};
    public int[][] updateMatrix(int[][] mat) {
        int m=mat.length;
        int n=mat[0].length;

        int[][] dis=new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                dis[i][j]=-1;
            }
        }
        Queue<int[]> q=new LinkedList<>();
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(mat[i][j]==0){
                    dis[i][j]=0;
                    q.add(new int[]{i,j});
                }
            }
        }

        while(!q.isEmpty()){
            int[] t=q.poll();
            int a=t[0];
            int b=t[1];
            for(int k=0;k<4;k++){
                int x=a+dx[k];
                int y=b+dy[k];
                if(x>=0 && x<m && y>=0 && y<n && dis[x][y]==-1){
                    dis[x][y]=dis[a][b]+1;
                    q.add(new int[]{x,y});
                }
            }
        }
        return dis;
    }
}

飞地的数量

1020. 飞地的数量 - 力扣(LeetCode)

class Solution {
    int[] dx={0,0,1,-1};
    int[] dy={1,-1,0,0};
    public int numEnclaves(int[][] grid) {
        int m=grid.length;
        int n=grid[0].length;
        Queue<int[]> q=new LinkedList<>();
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if((i==0 || i==m-1 || j==0 || j==n-1) && grid[i][j]==1){
                    grid[i][j]=2;
                    q.add(new int[]{i,j});
                }
            }
        }
        int ret=0;
        while(!q.isEmpty()){
            int[] t=q.poll();
            int a=t[0];
            int b=t[1];
            for(int k=0;k<4;k++){
                int x=a+dx[k];
                int y=b+dy[k];
                if(x>=0 && x<m && y>=0 && y<n && grid[x][y]==1){
                    grid[x][y]=2;
                    q.add(new int[]{x,y});
                }
            }
        }

        for(int i=1;i<m;i++){
            for(int j=1;j<n;j++){
                if(grid[i][j]==1)
                ret++;
            }
        }
        return ret;
    }
}

地图上的最高点

1765. 地图中的最高点 - 力扣(LeetCode)

class Solution {
    int[] dx={0,0,1,-1};
    int[] dy={1,-1,0,0};
    public int[][] highestPeak(int[][] isWater) {
        int m=isWater.length;
        int n=isWater[0].length;
        int[][] height=new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                height[i][j]=-1;
            }
        }
        Queue<int[]> q=new LinkedList<>();
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(isWater[i][j]==1){
                    height[i][j]=0;
                    q.add(new int[]{i,j});
                }
            }
        }
        while(!q.isEmpty()){
            int[] t=q.poll();
            int a=t[0];
            int b=t[1];
            for(int k=0;k<4;k++){
                int x=a+dx[k];
                int y=b+dy[k];
                if(x>=0 && x<m && y>=0 && y<n && height[x][y]==-1){
                    height[x][y]=height[a][b]+1;
                    q.add(new int[]{x,y});
                }
            }
        }
        return height;
    }
}

地图分析

1162. 地图分析 - 力扣(LeetCode)

class Solution {
    int[] dx={0,0,1,-1};
    int[] dy={1,-1,0,0};
    public int maxDistance(int[][] grid) {
        int m=grid.length;
        int n=grid[0].length;
        int[][] dis=new int[m][n];
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                dis[i][j]=-1;
            }
        }
        Queue<int[]> q=new LinkedList<>();
        for(int i=0;i<m;i++){
            for(int j=0;j<n;j++){
                if(grid[i][j]==1){
                    dis[i][j]=0;
                    q.add(new int[]{i,j});
                }
            }
        }
        int ret=-1;
        while(!q.isEmpty()){
            int[] t=q.poll();
            int a=t[0];
            int b=t[1];
            for(int i=0;i<4;i++){
                int x=a+dx[i];
                int y=b+dy[i];
                if(x>=0 && x<m && y>=0 && y<n && dis[x][y]==-1){
                    dis[x][y]=dis[a][b]+1;
                    q.add(new int[]{x,y});
                    ret=Math.max(ret,dis[x][y]);
                }
            }
        }

        
        return ret;
        
    }
}

BFS 解决拓扑排序

课程表

207. 课程表 - 力扣(LeetCode)

class Solution {
    public boolean canFinish(int numCourses, int[][] prerequisites) {
        int[] in=new int[numCourses];
        Map<Integer,List<Integer>> hash=new HashMap<>();
        for(int i=0;i<prerequisites.length;i++){
            int a=prerequisites[i][0];
            int b=prerequisites[i][1];
            if(!hash.containsKey(b)){
                hash.put(b,new ArrayList<>());
            }
            hash.get(b).add(a);
            in[a]++;
        }

        Queue<Integer> q=new LinkedList<>();
        for(int i=0;i<numCourses;i++){
            if(in[i]==0){
                q.add(i);
            }
        }

        while(!q.isEmpty()){
            int t=q.poll();
            // getOrDault(t,new ArrayList<>()))防止t为空
            for(int a:hash.getOrDefault(t,new ArrayList<>())){
                in[a]--;
                if(in[a]==0){
                    q.add(a);
                }
            }
        }

        for(int x:in){
            if(x!=0){
                return false;
            }
        }
        return true;
    }
}

课程表Ⅱ

210. 课程表 II - 力扣(LeetCode)

class Solution {
    public int[] findOrder(int numCourses, int[][] prerequisites) {
        int[] in=new int[numCourses];
        Map<Integer,List<Integer>> hash=new HashMap<>();
        for(int i=0;i<prerequisites.length;i++){
            int a=prerequisites[i][0];
            int b=prerequisites[i][1];
            if(!hash.containsKey(b)){
                hash.put(b,new ArrayList<>());
            }
            in[a]++;
            hash.get(b).add(a);
        }

        Queue<Integer> q=new LinkedList<>();
        for(int i=0;i<numCourses;i++){
            if(in[i]==0){
                q.add(i);
            }
        }
        int[] ret=new int[numCourses];
        int index=0;
        while(!q.isEmpty()){
            int t=q.poll();
            ret[index++]=t;
            for(int num:hash.getOrDefault(t,new ArrayList<>())){
                in[num]--;
                if(in[num]==0){
                    q.add(num);
                }
            }
        }
        for(int x:in){
            if(x!=0){
                return new int[0];
            }
        }
        return ret;
    }
}

火星字典(⭐)

LCR 114. 火星词典 - 力扣(LeetCode)

class Solution {
    Map<Character, Set<Character>> edges = new HashMap<>();
    Map<Character, Integer> in = new HashMap<>();
    boolean check = false;

    public String alienOrder(String[] words) {
        for (String s : words) {
            for (char ch : s.toCharArray()) {
                in.putIfAbsent(ch, 0);
            }
        }

        for (int i = 0; i < words.length - 1; i++) {
            add(words[i], words[i + 1]);
            if (check) return "";
        }

        Queue<Character> q = new LinkedList<>();
        for (char ch : in.keySet()) {
            if (in.get(ch) == 0) q.add(ch);
        }

        StringBuilder ret = new StringBuilder();
        while (!q.isEmpty()) {
            char t = q.poll();
            ret.append(t);
            if (!edges.containsKey(t)) continue;
            for (char ch : edges.get(t)) {
                in.put(ch, in.get(ch) - 1);
                if (in.get(ch) == 0) q.add(ch);
            }
        }

        for (int val : in.values()) {
            if (val != 0) return "";
        }

        return ret.toString();
    }

    public void add(String s1, String s2) {
        int n = Math.min(s1.length(), s2.length());
        int i = 0;
        for (; i < n; i++) {
            char c1 = s1.charAt(i), c2 = s2.charAt(i);
            if (c1 != c2) {
                edges.computeIfAbsent(c1, k -> new HashSet<>());
                if (edges.get(c1).add(c2)) {
                    in.put(c2, in.get(c2) + 1);
                }
                return;
            }
        }
        if (i == s2.length() && s1.length() > s2.length()) check = true;
    }
}

评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值