BFS&DFS
BFS和DFS有一点需要注意,我们几乎是一定会对一个节点进行多次遍历,所以我们一定要注意,遍历一次以后记得更改该节点状态。
BFS
广度优先遍历的意思很明确,先对我们的当前节点的比较近的进行遍历。然后一点点往远处探索。
这个时候我们就会有一个问题
- 如何获取附近节点
- 如何先遍历附近节点
既然是遍历,那么一定会有遍历规则,所以我们根据规则进行遍历即可。那么第二个问题,我们如何先遍历附近节点。
我们知道有一个数据结构队列,可以先进先出。我们只需要把先遍历的附近的放进去,然后继续遍历即可。而遍历也就是循环的结束条件就是我们的队列中没有数据。
DFS
深度优先就更好理解了,一条路走到不能走为止,然后走另一条。我们可以通过栈来进行先进后出,也可以通过递归来进行深度优先。
题目
假设我们要将一个二维数组中的一个数字改为新的数字,同时与他相同的上下左右的数字也会改为新数字,然后新改的数字的上下左右也会改为新数字。
广度优先遍历:
static public int[][] bfs(int[][] arr, int sr, int sc, int newNum) {
int n = arr.length;
int m = arr[0].length;
int curNum = arr[sr][sc];
if(curNum==newNum){
return arr;
}
Queue<int[]> queue = new LinkedList<>();
queue.offer(new int[]{sr,sc});
while (!queue.isEmpty()){
int[] cell = queue.poll();
int x = cell[0];
int y = cell[1];
if(x<0||x>=n||y<0||y>=m||arr[x][y]!=curNum){
continue;
}
arr[x][y] = newNum;
queue.offer(new int[]{x-1,y});
queue.offer(new int[]{x+1,y});
queue.offer(new int[]{x,y-1});
queue.offer(new int[]{x,y+1});
}
return arr;
}
深度优先遍历:
static int[] dx = {1, 0, 0, -1};
static int[] dy = {0, 1, -1, 0};
static public void dfs(int[][] arr, int x, int y, int num, int newNum) {
if(arr[x][y]==num){
arr[x][y] = newNum;
for (int i = 0; i < 4; i++) {
int mx = x + dx[i], my = y + dy[i];
if (mx >= 0 && mx < arr.length && my >= 0 && my < arr[0].length) {
dfs(arr,mx,my,num,newNum);
}
}
}
}