DFS_深度优先搜索经典案例

文章目录

        • 案例1
        • 案例2:
        • 案例3:
        • 案例4
        • 案例5

案例1

力扣:员工重要性


class Solution {
    //深度优先搜索核心代码
    //传参:unordered_map存储着所有员工的信息 id-Employee*
    int DFS(unordered_map<int, Employee*>& info, int id) {
        //计算当前员工个人的重要度curImportant
        int curImportant = info[id]->importance;
        //循环+递归:curImportant += 当前员工下属的重要度
        for (auto& sid : info[id]->subordinates) {
            curImportant += DFS(info, sid);
        }
        //最终返回当前员工和他的下属的重要度之和
        return curImportant;
    }
public:
    int getImportance(vector<Employee*> employees, int id) {
        //如果员工信息为空,直接返回0
        if (employees.empty())
            return 0;
        //将所有员工信息存储在unorder_map中,id - Employee*
        unordered_map<int, Employee*> info;
        for (auto e : employees) {
            info[e->id] = e;
        }
        return DFS(info, id);
    }
};

案例2:

力扣:图像渲染

class Solution {
public:
	//定义一个二维数组表示四个方向
	int nextPos[4][2] = { {1, 0}, {-1, 0}, {0, 1}, {0, -1} };
	//深度优先搜索
	void DFS(vector<vector<int>>& image, int row, int col, vector<vector<int>>& book,
		int sr, int sc, int oldColor, int newColor) {
		//渲染当前位置
		image[sr][sc] = newColor;
		book[sr][sc] = 1;
		//向四周四个方向扩散
		for (int i = 0; i < 4; ++i) {
			int newsr = sr + nextPos[i][0];
			int newsc = sc + nextPos[i][1];
			//检查坐标合理性
			if (newsr >= row || newsr < 0 || newsc >= col || newsc < 0)
				continue;
			//如果像素值相同并且当前位置没有被渲染过,则进行渲染
			if (image[newsr][newsc] == oldColor && book[newsr][newsc] == 0) {
				DFS(image, row, col, book, newsr, newsc, oldColor, newColor);
			}
		}
	}
	vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
		if (image.empty())
			return image;
		int row = image.size();
		int col = image[0].size();
		//book 用来标记当前位置是否被渲染过 默认没有被渲染-0
		vector<vector<int>> book(row, vector<int>(col, 0));
		//记录(sr,sc)位置的像素值
		int oldColor = image[sr][sc];
		DFS(image, row, col, book, sr, sc, oldColor, newColor);
		return image;
	}
};

案例3:

力扣:被围绕的区域

class Solution {
public:
    //定义数组表示四个不同的方向
    int nextPos[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    void DFS(vector<vector<char>>& board, int row, int col, int r, int c) {
        board[r][c] = '*';
        //向四个不同的方向寻找
        for (int i = 0; i < 4; ++i) {
            int newr = r + nextPos[i][0];
            int newc = c + nextPos[i][1];
            if (newr >= row || newr < 0 || newc >= col || newc < 0)
                continue;
            if (board[newr][newc] == 'O') {
                DFS(board, row, col, newr, newc);
            }
        }
    }
    void solve(vector<vector<char>>& board) {
        if (board.empty())
            return;
        //第一列和最后一列
        int row = board.size();
        int col = board[0].size();
        for (int i = 0; i < row; ++i) {
            if (board[i][0] == 'O')
                DFS(board, row, col, i, 0);
            if (board[i][col-1] == 'O')
                DFS(board, row, col, i, col-1);
        }
        //第一行和最后一行
        for (int j = 0; j < col; ++j) {
            if (board[0][j] == 'O')
                DFS(board, row, col, 0, j);
            if (board[row-1][j] == 'O')
                DFS(board, row, col, row-1, j);
        }
        
        //搜索完毕,所有被围绕的O还是O,但是没有被围绕的O变为了*
        //做最后的调整
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                if (board[i][j] == 'O')
                    board[i][j] = 'X';
                if (board[i][j] == '*')
                    board[i][j] = 'O';
            }
        }
    }
};

案例4

力扣:岛屿数量

class Solution {
public:
    //四个搜索方向
    int nextPos[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    //深度优先搜索
    void DFS(vector<vector<char>>& grid, int row, int col, int r, int c) {
        grid[r][c] = '#';
        //向四个方向搜索,将这一块岛屿全部标记为#
        for (int i = 0; i < 4; ++i) {
            int newr = r + nextPos[i][0];
            int newc = c + nextPos[i][1];
            if (newr >= row || newr < 0 || newc >= col || newc < 0)
                continue;
            if (grid[newr][newc] == '1')
                DFS(grid, row, col, newr, newc);
        }
    }
    int numIslands(vector<vector<char>>& grid) {
        if (grid.empty())
            return 0;
        int row = grid.size();
        int col = grid[0].size();
        
        int ret = 0;
        //遍历整个数组,每当遇到陆地,就将整个岛屿标记,并且 ++ret
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                if (grid[i][j] == '1') {
                    DFS(grid, row, col, i, j);
                    ++ret;                    
                }
            }
        }
        return ret;
    }
};

案例5

力扣:岛屿的最大面积

class Solution {
public:
    //四个搜索方向
    int nextPos[4][2] = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}};
    //深度优先搜索
    int DFS(vector<vector<int>>& grid, int row, int col, int r, int c) {
        int ret = 1;
        grid[r][c] = 0;
        for (int k = 0; k < 4; ++k) {
            int newr = r + nextPos[k][0];
            int newc = c + nextPos[k][1];
            if (newr >= row || newr < 0 || newc >= col || newc < 0)
                continue;
            if (grid[newr][newc] == 1) {
                ret += DFS(grid, row, col, newr, newc);
            }
        }
        return ret;
    }
    int maxAreaOfIsland(vector<vector<int>>& grid) {
        if (grid.empty())
            return 0;
        int row = grid.size();
        int col = grid[0].size();
        //max 存储最大的岛屿面积
        int max = 0;
        for (int i = 0; i < row; ++i) {
            for (int j = 0; j < col; ++j) {
                if (grid[i][j] == 1) {
                    int tmp = DFS(grid, row, col, i, j);
                    if (tmp > max)
                        max = tmp;
                }
            }
        }
        return max;
    }
};

你可能感兴趣的:(数据结构&&算法,刷题)