1 深度优先搜索的关键是解决 -> 目前需要如何做 ,下一步的做法和当前的做法是相同的
2 目前需要如何做 -> 一般是尝试每一种可能,遍历循环,对于每一种可能确定之后,继续走下一步,当前的剩余可能等到从下一步回退之后再处理,(深度优先搜索的模型)
Dfs (当前这一步的处理逻辑)
{
1.判断边界,是否已经一条路走到黑 :向上回退
2.尝试当下的每一种可能
3.确定一种可能后,继续下一步Dfs(下一步)
}
例题1:员工的重要性
思路 : 哈希表+dfs
哈希表<id,Employee> dfs 员工重要性
import java.util.HashMap;
import java.util.List;
import java.util.Map;
public class Solution {
class Employee {
public int id;
public int importance;
public List<Integer> subordinates;
}
public int dfs(Map<Integer,Employee> map ,int id){
int curRet = map.get(id).importance;
for (int suBid: map.get(id).subordinates) {
curRet += dfs(map,suBid);
}
return curRet;
}
public int getImportance(List<Employee> employees, int id) {
Map<Integer,Employee> map = new HashMap<>();
for ( Employee e : employees
) {
map.put(e.id,e);
}
return dfs(map,id);
}
}
例题2:图像渲染
思路:
public class Solution {
int [] dx = {1,-1,0,0};
int [] dy = {0,0,1,-1};
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int curColor = image[sr][sc]; // 获取当前color
if (curColor!=newColor){
dfs(image,sr,sc,curColor,newColor); // dfs深度优先搜索
}
return image;
}
public void dfs(int[][] image ,int x ,int y, int color ,int newColor){
if (image[x][y]==color){
image[x][y]=newColor;
for (int i = 0; i <4 ; i++) {
int mx = x + dx[i] , my = y + dy[i];
if ( mx>=0 && mx<image.length && my>=0 && my<image[0].length){
dfs(image,mx,my,color,newColor);
}
}
}
}
}
例题3:岛屿的周长
例题4:被围绕的区域
思路:
找到未被包围的O进行深度优先搜索进行标记,最近遍历整个数组,把未被标记的O改为X ,标记过得恢复
public class Solution3 {
private int row ,col;
int [] dx = {1,-1,0,0};
int [] dy = {0,0,1,-1};
private void dfs (char[][] board,int x ,int y ){
if (x<0 || y<0 || x>= row || y>=col || board[x][y]!='O'){
return;
}
board[x][y]='+';
for (int i = 0; i <4 ; i++) {
int mx = x + dx[i] , my = y + dy[i];
dfs(board,mx,my);
}
}
public void solve(char[][] board) {
row = board.length;
col = board[0].length;
if ( row==0 || col==0){
return;
}
for (int i = 0; i <row ; i++) {
dfs(board,i,0); //第一行
dfs(board,i,col-1); //最后一行
}
for (int i = 0; i <col ; i++) {
dfs(board,0,i); //第一列
dfs(board,row-1,i); //最后一列
}
for (int i = 0; i <row ; i++) {
for (int j = 0; j <col ; j++) {
if (board[i][j]=='O'){ // 被包围的'0'
board[i][j]='X';
}else if (board[i][j]=='+'){// 未被包围的'0
board[i][j]='O';
}
}
}
}
}
例题5:岛屿数量
思路:找到一个1的位置,并向周围进行dfs,将其标记为0,这是搜索一个岛屿次数。记录这个次数,就是岛屿的数量。
public class Solution5 {
int [] dx = {1,-1,0,0};
int [] dy = {0,0,1,-1};
public int numIslands(char[][] grid) {
int row =grid.length;
int col = grid[0].length;
int num = 0;
for (int i = 0; i <row ; i++) {
for (int j = 0; j <col ; j++) {
if (grid[i][j]=='1'){
num++;
dfs(grid,i,j);
}
}
}
return num;
}
private void dfs(char[][] grid, int x, int y) {
if (x < 0 || x >= grid.length || y < 0 || y >= grid[0].length || grid[x][y]=='0'){
return;
}
grid[x][y]='0' ;
for (int i = 0; i < 4; i++) {
int mx = x + dx[i], my = y + dy[i];
{
dfs(grid, mx, my);
}
}
}
}
例题6:矩阵中的路径
思路:深度优先搜索(DFS)+ 剪枝
public class Solution {
public boolean exist (char[][] board, String word) {
char [] words = word.toCharArray();
int n = board.length;
int m = board[0].length;
for (int i = 0; i <n ; i++) {
for (int j = 0; j <m ; j++) {
if (dfs(board,words,i,j,0)) return true;
}
}
return false;
}
private boolean dfs(char[][] board, char[] word, int i, int j, int k) {
if ( i>=board.length || i<0 || j>=board[0].length || j<0 || board[i][j]!=word[k] ) {
return false;
}
if (k == word.length-1) return true;
board[i][j]='\0';
boolean res = dfs(board, word, i + 1, j, k + 1) || dfs(board, word, i - 1, j, k + 1) ||
dfs(board, word, i, j + 1, k + 1) || dfs(board, word, i , j - 1, k + 1);
board[i][j] = word[k];
return res;
}
}