深度优先搜索(DFS)

您所在的位置:网站首页 图的算法题 深度优先搜索(DFS)

深度优先搜索(DFS)

2023-08-08 14:21| 来源: 网络整理| 查看: 265

欢迎访问我的blog http://www.codinglemon.cn/

0. 深度优先搜索(DFS)

先简单了解一下DFS,其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个节点只访问一次。

DFS思修基于递归思想,通过递归的形式来缩小问题规模,把一件事分割成若干个相同的小事,逐步完成。

深度优先搜索的步骤分为 1.递归下去 2.回溯上来。顾名思义,深度优先,则是以深度为准则,先一条路走到底,直到达到目标。这里称之为递归下去。

否则既没有达到目标又无路可走了,那么则退回到上一步的状态,走其他路。这便是回溯上来。

下面直接看题吧。

1. LeetCode 733. 图像渲染 1.1 题目描述

有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。

给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。

为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。

最后返回经过上色渲染后的图像。

示例 1:

输入: image = [[1,1,1],[1,1,0],[1,0,1]] sr = 1, sc = 1, newColor = 2 输出: [[2,2,2],[2,2,0],[2,0,1]] 解析: 在图像的正中间,(坐标(sr,sc)=(1,1)), 在路径上所有符合条件的像素点的颜色都被更改成2。 注意,右下角的像素没有更改为2, 因为它不是在上下左右四个方向上与初始点相连的像素点。

注意:

image 和 image[0] 的长度在范围 [1, 50] 内。给出的初始点将满足 0 int oldColor = image[sr][sc]; if(oldColor != newColor){ replaceOldColor(image,sr,sc,oldColor,newColor); } return image; } public void replaceOldColor(int[][] image, int sr, int sc,int oldColor,int newColor){ if(sr =image[0].length || image[sr][sc] != oldColor){ return; } image[sr][sc] = newColor; //上 replaceOldColor(image,sr-1,sc,oldColor,newColor); //下 replaceOldColor(image,sr+1,sc,oldColor,newColor); //左 replaceOldColor(image,sr,sc-1,oldColor,newColor); //右 replaceOldColor(image,sr,sc+1,oldColor,newColor); } }

这里编写找寻上下左右的点的代码不太优美,下面的题解中有比较优美的解决办法。

2. LeetCode 695. 岛屿的最大面积 2.1 题目描述

给定一个包含了一些 0 和 1 的非空二维数组 grid 。

一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在水平或者竖直方向上相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。

找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 0 。)

示例 1:

[[0,0,1,0,0,0,0,1,0,0,0,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,1,1,0,1,0,0,0,0,0,0,0,0], [0,1,0,0,1,1,0,0,1,0,1,0,0], [0,1,0,0,1,1,0,0,1,1,1,0,0], [0,0,0,0,0,0,0,0,0,0,1,0,0], [0,0,0,0,0,0,0,1,1,1,0,0,0], [0,0,0,0,0,0,0,1,1,0,0,0,0]]

对于上面这个给定矩阵应返回 6。注意答案不应该是 11 ,因为岛屿只能包含水平或垂直的四个方向的 1。

示例 2:

[[0,0,0,0,0,0,0,0]]

对于上面这个给定的矩阵, 返回 0。

注意: 给定的矩阵grid 的长度和宽度都不超过 50。

来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/max-area-of-island 著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

2.2 解题思路

这个题跟前面的题其实解题思路类似,只不过他的基准点是从坐标(0,0)开始顺序向下一直找的。聪明的同学就会发现一个问题,如果我们像上一个题这么写,那执行时间不是爆炸?**因为每设置一个新的基准点,就通过这个基准点向4个方向去找与他相邻的1,肯定会有非常非常多重复的查找情况。**比如:

现在有[[1,1],[1,1]]这样一个数组,那么如果按上一个方法去找,每个1都会去查找一次,虽然最后结果返回的是4,但是查找重复了3次,这还只是一个2X2的数组,如果是50X50的数组,查找重复的次数将大大增长。

那么怎么去解决这个问题呢?其实可以在每次查找到值为1的点后,将该点的值置为0,表明这个地方已经查找过了,下次再查找相同的区块,就不会重复了。

这里的置0也可以这么理解,也就是说我查找到某一个岛屿并计算出他的面积之后,将该岛屿从地图上直接剔除(因为标0就默认该区域无岛屿),再去计算其他岛屿,防止重复计算。

解题步骤如下:

从给定点开始,先判断给定点是否超出边界或给定点的值是否为1,如果不为1或超出边界则返回0若给定点值为1,则将给定点的值置为0,将结果answer置为1,且递归的查找给定点上下左右4个方向上的点,将递归结果累加到answer上,然后返回answer值。取当前answer值与递归方法返回的answer值中的较大值,循环每个基准点结束后,返回结果。 2.3 解题代码 class Solution { public int maxAreaOfIsland(int[][] grid) { int ans = 0; for(int i=0;i ans = Math.max(ans,findOne(grid,i,j)); } } return ans; } public int findOne(int[][] grid,int i,int j){ if(i 0,0,1,-1}; int[] dj = {1,-1,0,0}; grid[i][j] = 0; int ans = 1; for(int k=0;k


【本文地址】


今日新闻


推荐新闻


CopyRight 2018-2019 办公设备维修网 版权所有 豫ICP备15022753号-3