leetcode--200--python(深度广度优先遍历实现代码)
点滴积累,厚积薄发,做好每一天,向时间要效率,向生命要质量。
一、深度优先搜索和广度优先搜索
DFS(Depth-First-Search),是盲目搜索算法的一种。常常用在树的遍历及图的处理上。假设当前搜索的节点记为k,深度优先搜索表示,继续探寻k节点的所有的边。搜索过程中,遇到满足条件的k+1节点,则继续搜索探寻k+1节点的所有的边。最后回溯至节点k。这个过程一直进行到已发现从源节点开始可以到达的所有节点位置。
**深度优先遍历图算法步骤:
访问起始点k;
依次从k的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和k有路径相通的顶点都被访问;
若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。
BFS(Breadth-First-Search),BFS同样属于盲目搜索算法,常常使用队列(先进先出)的数据结构来辅助实现。在python中,可以使用堆栈(pop(0))的性质进行实现。BFS是从源节点开始,沿着树(图)的宽度遍历树(图)的节点。将未被访问的节点依次压入队列,再依次读取进行遍历,直到队列为空,所有节点均被访问,算法终止。
广度优先遍历图算法步骤:
首先将源节点放入队列中。
从队列中取出第一个节点,检验其是否满足要求。根据条件回传结果,并将它所有尚未检验过的满足条件的子节点加入队列中。
若队列为空,表示整张图都检查过了——亦即图中没有未搜寻的目标。结束搜寻并回传结果。
若队列不为空,若重复步骤2。
DFS和BFS比较:通常情况下,DFS的速度较快,且可以不适用额外的辅助空间。
题目:给定一个由 '1'(陆地)和 '0'(水)组成的的二维网格,计算岛屿的数量。一个岛被水包围,并且它是通过水平方向或垂直方向上相邻的陆地连接而成的。
你可以假设网格的四个边均被水包围。
示例 1:
输入:
11110
11010
11000
00000
输出: 1
示例 2:
输入:
11000
11000
00100
00011
输出: 3
注意点:
(1)无论DFS还是BFS,在涉及到图中上下左右搜索的问题时,一般都要建立方向数组,表示向四个方向依次遍历。
dx = [-1,1,0,0]
dy = [0,0,-1,1]
(2) python中的可变对象和不可变对象传值问题。list、dict为可变对象,作为参数传递时,对象位置不发生改变。string、tuple以及int为不可变对象。
1、DFS算法思路:
建立一个mark数组,记录grid中满足条件的陆地‘1’对应的位置是否已被访问。
(1)标记当前搜索位置已被搜索(标记当前位置的mark数组为1)
(2)按照方向数组的四个方向,扩展4个新位置newx,newy
(3) 若新位置不在地图范围内,则忽略
(4)如果新位置未曾到达过(mark[newx][newy]为0)、且是陆地(grid[newx][newy]为‘1’),继续DFS该位置
class Solution(object):
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
res = 0
if len(grid) == 0:
return res
m = len(grid)
n = len(grid[0]) mark = [[0] * n for i in range(m)] for i in range(m):
for j in range(n):
if mark[i][j] == 0 and grid[i][j] == '1':
self.dfs(mark, grid, i, j)
res += 1
return res # 深度优先搜索:时间优于宽度优先搜索
def dfs(self, mark, grid, x, y):
mark[x][y] = 1
dx = [-1, 1, 0, 0] # 方向数组
dy = [0, 0, -1, 1]
m = len(grid)
n = len(grid[0])
# 遍历上下左右四个方向
for i in range(4):
newx = dx[i] + x
newy = dy[i] + y
if newx < 0 or newx >= m or newy >= n or newy < 0:
continue
if mark[newx][newy] == 0 and grid[newx][newy] == '1':
self.dfs(mark, grid, newx, newy) s = Solution()
nums = [['1','1',0,0,0],['1','1',0,0,0],[0,0,'1',0,'1']]
print(s.numIslands(nums))
2、BFS算法思路:
建立一个mark数组,记录grid中满足条件的陆地‘1’对应的位置是否已被访问。建立一个队列,搜索使用。
(1)设置搜索队列Q(或能够满足FIFO的其他数据结构),标记mark[x][y]为1,并将待搜索的位置(x,y)push进入队列Q。
(2)只要队列不为空,则取队头元素,按照方向数组的4个方向,拓展4个新位置newx,newy。
(3)若新位置不在地图范围内, 则忽略。
(4)如果新位置未曾到达过(mark[newx][newy]为0)、 且是陆地(grid[newx][newy]为“1”),该新位置push进入队列, 并标记mark[newx][newy] = 1。
class Solution(object):
def numIslands(self, grid):
"""
:type grid: List[List[str]]
:rtype: int
"""
res = 0
if len(grid) == 0:
return res
m = len(grid)
n = len(grid[0]) mark = [[0] * n for i in range(m)] for i in range(m):
for j in range(n):
if mark[i][j] == 0 and grid[i][j] == '1':
self.bfs(mark, grid, i, j)
res += 1
return res # 深度优先搜索:时间优于宽度优先搜索
def bfs(self, mark, grid, x, y):
Q = []
Q.append([x,y])
mark[x][y] = 1
dx = [-1, 1, 0, 0] # 方向数组
dy = [0, 0, -1, 1]
m = len(grid)
n = len(grid[0])
# 遍历上下左右四个方向
while Q:
temp = Q.pop(0)
x = temp[0]
y = temp[1]
for i in range(4):
newx = dx[i]+x
newy = dy[i]+y
if newx < 0 or newx >= m or newy >= n or newy < 0:
continue
if mark[newx][newy] == 0 and grid[newx][newy] == '1':
Q.append([newx, newy]) # 将新位置进入队列
mark[newx][newy] = 1 s = Solution()
nums = [['1','1',0,0,0],['1','1',0,0,0],[0,0,'1',0,'1']]
print(s.numIslands(nums))
leetcode--200--python(深度广度优先遍历实现代码)的更多相关文章
- python 实现二叉树的深度 & 广度优先遍历
什么是树 在计算器科学中,树(英语:tree)是一种抽象数据类型(ADT)或是实现这种抽象数据类型的数据结构,用来模拟具有树状结构性质的数据集合.它是由n(n>0)个有限节点组成一个具有层次关系 ...
- 【Warrior刷题笔记】剑指offer 32. 三道题,让你学会二叉树的深度广度优先遍历与递归迭代技术
题目一 剑指 Offer 32 - I. 从上到下打印二叉树 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/cong-shang-dao-xi ...
- 【算法】【python实现】二叉树深度、广度优先遍历
二叉树的遍历,分为深度优先遍历,以及广度优先遍历. 在深度优先遍历中,具体分为如下三种: 先序遍历:先访问根节点,再遍历左子树,再遍历右子树: 中序遍历:先遍历左子树,再访问根节点,再遍历右子树: 后 ...
- 数据结构-树以及深度、广度优先遍历(递归和非递归,python实现)
前面我们介绍了队列.堆栈.链表,你亲自动手实践了吗?今天我们来到了树的部分,树在数据结构中是非常重要的一部分,树的应用有很多很多,树的种类也有很多很多,今天我们就先来创建一个普通的树.其他各种各样的树 ...
- python、java实现二叉树,细说二叉树添加节点、深度优先(先序、中序、后续)遍历 、广度优先 遍历算法
数据结构可以说是编程的内功心法,掌握好数据结构真的非常重要.目前基本上流行的数据结构都是c和c++版本的,我最近在学习python,尝试着用python实现了二叉树的基本操作.写下一篇博文,总结一下, ...
- 数据结构5_java---二叉树,树的建立,树的先序、中序、后序遍历(递归和非递归算法),层次遍历(广度优先遍历),深度优先遍历,树的深度(递归算法)
1.二叉树的建立 首先,定义数组存储树的data,然后使用list集合将所有的二叉树结点都包含进去,最后给每个父亲结点赋予左右孩子. 需要注意的是:最后一个父亲结点需要单独处理 public stat ...
- 图的存储及遍历 深度遍历和广度遍历 C++代码实现
/*图的存储及遍历*/ #include<iostream> using namespace std; //----------------------------------- //邻接 ...
- python算法-二叉树广度优先遍历
广度优先遍历:优先遍历兄弟节点,再遍历子节点 算法:通过队列实现-->先进先出 广度优先遍历的结果: 50,20,60,15,30,70,12 程序遍历这个二叉树: # encoding=utf ...
- 树的深度优先遍历和广度优先遍历的原理和java实现代码
import java.util.ArrayDeque; public class BinaryTree { static class TreeNode{ int value; TreeNode le ...
随机推荐
- Java中null的判断
Java中空指针的异常十分常见 if (name != null && !name.equals("")) { //do something } 或者 if (!& ...
- Spring源码分析——(001)环境搭建
1.官方参考 spring-framework的github链接:https://github.com/spring-projects/spring-framework 源码环境搭建官方参考1:考如何 ...
- 分享一个php加密字符串类。
class base64{ /** * 加密字符串 * @access static * @param string $data 字符串 * @param string $key 加密key * @r ...
- AFNetworking实现表单(multipart)形式上传图片
最近遇到个问题,就是上传图片到服务器,后台说用表单形式... 由于没弄过这种上传,所以搜了大堆资料,但也没解决问题. 最后通过请教一位大神才得以解决这个简单的问题... 现在将此方法做个笔记... & ...
- 无法启动APK安装也,报异常FileUriExposedException
无法打开APK安装页,报异常FileUriExposedException, https://juejin.im/entry/58e4643db123db15eb79a902
- vue学习(八)nextTick[异步更新队列]的使用和应用
nextTick的使用 为了数据变化之后等待vue完成更新DOM,可以在数据变化之后立即使用Vue.nextTick()在当前的回调函数中能获取最新的DOM <div id="app& ...
- 设置此div的子元素居中显示
下面样式设置到父div上: .modal { display: flex; align-items: center; /*竖直居中 垂直居中*/ justify-content: center; /* ...
- SpringBoot实现OAuth2认证服务器
一.最简单认证服务器 1. pom依赖 <dependency> <groupId>org.springframework.boot</groupId> <a ...
- linux下的 sudo ln -s 源文件 目标文件
这是linux中一个非常重要命令,请大家一定要熟悉.它的功能是为某一个文件或目录在另外一个位置建立一个同步的链接,类似Windows下的超级链接. 这个命令最常用的参数是-s,具体用法是:sudo l ...
- 每天一点点之vue框架开发 - 使用vue-router路由
1.安装路由(安装过的跳过此步) // 进入项目根目录 cd frontend // 安装 npm install vue-router --save-dev 2.在入口文件main.js中引入路由 ...