广度优先搜索 / 深度优先搜索
广度优先搜索:每一层进行遍历
深度优先搜索:每一列进行遍历
因为最近在刷leetcode初级算法,做到了广度优先搜索和深度优先搜索的地方,发现有些题目呀还是不能一下解出 ,在此进行记录解题
第 7 天
733. 图像渲染
图像渲染可以看做画图里面的油漆桶工具
该题目使用深度优先遍历,我们需要先找到初始格子的颜色,然后将他周围的格子依次同化即可,这个过程其实是依次完成的,需要从初始格子依次开始上下左右的遍历
class Solution {
int[] dx = {1,0,0,-1};
int[] dy = {0,1,-1,0};
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int currColor = image[sr][sc]; // 初始格子的颜色,接下来要对他周围的格子进行同化
if (currColor != newColor) { // 初始格子要是和新颜色相同,就直接返回数组即可
dfs(image,sr,sc,currColor,newColor); // 进行深度优先遍历,传入了初始元素
}
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);
}
}
}
}
}
695. 岛屿的最大面积
这道题目的思想和上面的那道其实是一样的,只不过在实现上有些区别
假设我们现在在任意一处岛屿的任意的一个位置,我们首先需要去判断当前位置所在的岛屿的面积,这个时候就是去使用和上面一样的广度优先遍历即可,依次对格子进行上下左右的遍历,最后记录这个岛屿的面积
为了避免重复去遍历,我们可以将走过的陆地置0
class Solution {
public int maxAreaOfIsland(int[][] grid) {
int ans = 0; // 最大岛屿面积
// 对地图进行遍历
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
ans = Math.max(ans, dfs(grid, i, j));// 比较最大岛屿面积
}
}
return ans;
}
public int dfs(int[][] grid, int curI, int curJ) {
// 如果当前格子不是陆地,直接返回0就行
if (curI < 0 || curJ < 0 || curI == grid.length || curJ == grid[0].length || grid[curI][curJ] != 1) {
return 0;
}
grid[curI][curJ] = 0; // 如果是,置0
int[] di = {0, 0, 1, -1}; // 进行 上下方向遍历
int[] dj = {1, -1, 0, 0}; // 进行 左右方向遍历
int ans = 1; // 每一个岛屿的ans面积
for (int index = 0; index < 4; index++) {
int nextI = curI + di[index], nextJ = curJ + dj[index];
ans += dfs(grid, nextI, nextJ);
}
return ans; // 返回当前岛屿的面积
}
}
第 8 天
617. 合并二叉树
使用递归去写,我们让两棵树以相同的步数去遍历,如果当前都不为空,就将值加到第一课树上对应的节点即可,如果遍历到第二棵树为空就返回第一颗树的节点,反之则返回第二颗树 的节点
class Solution {
public TreeNode mergeTrees(TreeNode root1, TreeNode root2) {
if(root1 == null || root2 == null) {
return root1 == null ? root2 : root1;
}
return dfs(root1,root2);
}
TreeNode dfs(TreeNode root1,TreeNode root2) {
if(root1 == null || root2 == null) {
return root1 == null ? root2 : root1;
}
root1.val += root2.val;
root1.left = dfs(root1.left,root2.left);
root1.right = dfs(root1.right,root2.right);
return root1;
}
}
116. 填充每个节点的下一个右侧节点指针
class Solution {
public Node connect(Node root) {
dfs(root);
return root;
}
void dfs(Node root) {
if(root==null) {
return;
}
Node left = root.left;
Node right = root.right;
//配合动画演示理解这段,以root为起点,将整个纵深这段串联起来
while(left!=null) {
left.next = right;
left = left.right;
right = right.left;
}
//递归的调用左右节点,完成同样的纵深串联
dfs(root.left);
dfs(root.right);
}
}