搜索引擎
提到搜索两个子,大家都应该会想到搜索引擎,搜索引擎的基本工作步骤;
网页爬取 — 数据预处理 — 排序 — 查询
第一步,网页爬取,非常重要,简单来说,就是给爬虫(蜘蛛程序或者爬虫机器人)分配一组起始的网页,爬取一个网页后,解析提取出这个网页里的所有超链接,再依次爬取出这些超链接,再提取网页超链接,如此不断重复,从而提取网页内容。
海量的网页链接之间最终构成了一张图,于是问题就变成了如何遍历这张图。
现在的网络,网站机构复杂,信息太多,所以蜘蛛爬行也是有一定策略的。基础就是广度优先和深度优先两种。现实确实时间和带宽优先,再大的搜索引擎也仅仅只能是收入小部分网页。提升网络爬虫的主要方法有:提升网站权重/频繁更新/导入链接/减短与首页的距离等等。
深度优先搜索属于图算法的一种(Depth First Search)。其过程简要来说就是对每一个可能的分支路径深入到不能深入为止,而且每一个节点只能访问一次。
深度优先搜索是每一次按照一个方向进行穷尽式的搜索,当该方向上的搜索无法继续往前的时候,这时候就退回到上一步,换一个方向继续搜索。
算法演示如下:
从跟节点开始,一直搜索左子树,直到某个节点没有左子树为止,接着换个方向搜索右子树。如图,
DFS的序列为(先序遍历):0 —> 1 —> 3 —> 4 —> 2 —> 5 —> 6
假设初始状态是图中所有顶点均未被访问,则从某个顶点v出发,首先访问该顶点,然后依次从它的各个未被访问的邻接点出发深度优先搜索遍历图,直至图中所有和v有路径相通的顶点都被访问到。
若此时尚有其他顶点未被访问到,则另选一个未被访问的顶点作起始点,重复上述过程,直至图中所有顶点都被访问到为止。
从顶点A开始深度优先搜索;
访问的顺序:A—C—B—D—F—G—E
访问顺序:A—B—C—E—D—F—G
https://leetcode.cn/problems/number-of-islands/description/
DFS(深度优先搜索)问题通常在树或者图结构上进行的,而这道提属于网络结构,网络结构要比二叉树结构稍微复杂,它其实是一个简化版的图结构。
分析:
思路:
主循环:
遍历整个矩阵,当遇到grid[i][j]==1时,从此点开始做深度优先搜索dfs,岛屿的数量+1且在深度优先搜索中删除此岛屿。
最终返回岛屿数量count。
class Solution:
def numIslands(self, grid: List[List[str]]) -> int:
def dfs(grid, i, j, rows, cols):
# 退出条件
if i < 0 or i > rows - 1 or j < 0 or j > cols - 1 or grid[i][j] != "1":
return
grid[i][j] = '0'
dfs(grid, i, j+1, rows, cols)
dfs(grid, i, j-1, rows, cols)
dfs(grid, i+1, j, rows, cols)
dfs(grid, i-1, j, rows, cols)
rows = len(grid)
if rows == 0:
return 0
cols = len(grid[0])
num_islands = 0
for i in range(rows):
for j in range(cols):
# 只有确认时岛屿,才会遍历
if grid[i][j] == '1':
# 发现岛屿,岛屿个数加1
num_islands += 1
dfs(grid, i, j, rows, cols)
return num_islands