BFS和DFS算法题总结

BFS:

BFS走迷宫从左上到右下,输出最短路径,中间有墙

输入:

5 5

0 1 0 0 0

0 1 0 1 0

0 0 0 0 0

0 1 1 1 0

0 0 0 1 0

输出:

DDRRRRDD

8

import java.util.*;

class Node{
    int row;
    int col;
    String str;//记录路径
    public Node(int row, int col, String tmp){
        this.row = row;
        this.col = col;
        this.str = tmp;
    }
}
public class bfsmain {
    private static int[][] dir = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
    public static void main(String[] args){
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int[][] nums = new int[n][m];
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                nums[i][j] = in.nextInt();
            }
        }

        Queue<Node> q = new ArrayDeque<>();
        int[][] dis = new int[n][m];// 存储每个节点到起点的距离
        String direc="UDLR";//要打印的方向
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                dis[i][j]=-1;
            }
        }
        dis[0][0] = 0;
        Node start = new Node(0,0,"");
        q.add(start);
        while(!q.isEmpty()){
            Node tmp = q.poll();
            if(tmp.row==n-1 && tmp.col==m-1){
                System.out.println(tmp.str);
                System.out.println(dis[n-1][m-1]);
                return;
            }
            for(int i=0;i<4;i++){
                int x = tmp.row + dir[i][0];
                int y = tmp.col + dir[i][1];
                if(x>=0 && x<n && y>=0 && y<m && nums[x][y]==0 && dis[x][y]==-1){
                    dis[x][y] = dis[tmp.row][tmp.col]+1;
                    q.add(new Node(x,y,tmp.str+direc.charAt(i)));
                }
            }
        }
        return;
    }  
}

DFS:

1.矩阵中的路径

请设计一个函数,用来判断在一个n乘m的矩阵中是否存在一条包含某长度为len的字符串所有字符的路径。路径可以从矩阵中的任意一个格子开始,每一步可以在矩阵中向左,向右,向上,向下移动一个格子。如果一条路径经过了矩阵中的某一个格子,则该路径不能再进入该格子。 例如矩阵中包含一条字符串"bcced"的路径,但是矩阵中不包含"abcb"路径,因为字符串的第一个字符b占据了矩阵中的第一行第二个格子之后,路径不能再次进入该格子。

输入: [[a,b,c,e],[s,f,c,s],[a,d,e,e]]

输出:abcced

import java.util.*;


public class Solution {
    /**
     * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
     *
     * 
     * @param matrix char字符型二维数组 
     * @param word string字符串 
     * @return bool布尔型
     */
    private int n;
    private int m;
    private int[][] pos = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
    public boolean dfs(char[][] matrix, int i, int j, int index, String word){
        if(word.charAt(index)!=matrix[i][j])
            return false;
        if(index==word.length()-1)
            return true;
        char tmp = matrix[i][j];
        matrix[i][j] = '.';
        for(int k=0;k<4;k++){
            int x = i+pos[k][0];
            int y = j+pos[k][1];
            if(x>=0 && x<n && y>=0 && y<m)
                if(dfs(matrix, x, y, index+1, word))
                    return true;
        }
        matrix[i][j] = tmp;
        return false;
    }
    public boolean hasPath (char[][] matrix, String word) {
        // write code here
        n = matrix.length;
        m = matrix[0].length;
        for(int i=0;i<n;i++){
            for(int j=0;j<m;j++){
                if(dfs(matrix, i, j, 0, word))
                    return true;
            }
        }
        return false;
    }
}

2.机器人的运动范围

地上有一个 rows 行和 cols 列的方格。坐标从 [0,0] 到 [rows-1,cols-1] 。一个机器人从坐标 [0,0] 的格子开始移动,每一次只能向左,右,上,下四个方向移动一格,但是不能进入行坐标和列坐标的数位之和大于 threshold 的格子。 例如,当 threshold 为 18 时,机器人能够进入方格   [35,37] ,因为 3+5+3+7 = 18。但是,它不能进入方格 [35,38] ,因为 3+5+3+8 = 19 。请问该机器人能够达到多少个格子?

输入:1,2,3

输出:3

public class Solution {

    private int n;
    private int m;
    private int[][] pos = new int[][]{{-1,0},{1,0},{0,-1},{0,1}};
    private int res=0;
    public int func(int num){
        int res =0;
        while(num!=0){
            res+=num%10;
            num/=10;
        }
        return res;
    }
    public void dfs(int threshold, int i, int j, boolean[][] used){
        if(used[i][j]==true)
            return;
        if(func(i)+func(j)>threshold)
            return;
        used[i][j] = true;
        res++;
        for(int k=0;k<4;k++){
            int x = i+pos[k][0];
            int y = j+pos[k][1];
            if(x>=0 && x<n && y>=0 && y<m){
                dfs(threshold, x, y, used);
            }
        }
        return;
    }
    public int movingCount(int threshold, int rows, int cols) {
        n = rows;
        m = cols;
        boolean used[][] = new boolean[n][m];
        dfs(threshold, 0, 0, used);
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值