695 岛屿的最大面积
DFS 深度优先,就是一条路走到黑。和stack(先进后出)一起使用。
深度优先搜索算法(英语:Depth-First-Search,DFS)是一种用于遍历或搜索树或图的算法。沿着树的深度遍历树的节点,尽可能深的搜索树的分支。当节点v的所在边都己被探寻过,搜索将回溯到发现节点v的那条边的起始节点。这一过程一直进行到已发现从源节点可达的所有节点为止。如果还存在未被发现的节点,则选择其中一个作为源节点并重复以上过程,整个进程反复进行直到所有节点都被访问为止。属于盲目搜索。
链接:https://leetcode-cn.com/tag/depth-first-search/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
图的DFS中还需要有独立的DFS,比如统计岛屿个数,在每个岛屿中都需要用DFS,那么需要在DFS的外面再套一层for 循环
For r in range(xxxx)
Stack.append(root)
以图的DFS为例
如果图为空,则返回空值
if not root: return []
res = []
建立set来存储入栈的元素
Traversed = set()
判断题目是多个root还是单root,首先初始化栈,
stack = [root]
遍历stack中的元素,逐个处理
while stack:
取出栈顶元素
pop = stack.pop()
遍历栈顶元素的邻居,如果符合条件(index不越界,不在set中,且满足xx条件),则入栈,且在入栈后加入set
res.append(pop.val)
将当前元素周围符合条件的都加到stack中
if 0 <= new_i < m and 0 <= new_j < n and not marked[new_i][new_j] and grid[new_i][new_j] == '1':
stack.append((new_i, new_j))
#【特别注意】在放入队列以后,要马上标记成已经访问过,语义也是十分清楚的:反正只要进入了队列,你迟早都会遍历到它,而不是在出队列的时候再标记
#【特别注意】如果是出队列的时候再标记,会造成很多重复的结点进入队列,造成重复的操作,这句话如果你没有写对地方,代码会严重超时的
marked[new_i][new_j] = True
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
广度优先的主要应用场景 542 矩阵
思路:
对于 「Tree 的 BFS」 (典型的「单源 BFS」) 大家都已经轻车熟路了:
首先把 root 节点入队,再一层一层无脑遍历就行了。
对于 「图 的 BFS」 (「多源 BFS」) 做法其实也是一样滴~,与 「Tree 的 BFS」的区别注意以下两条就 ok 辣~
Tree 只有 1 个 root,而图可以有多个源点,所以首先需要把多个源点都入队;
Tree 是有向的因此不需要标识是否访问过,而对于无向图来说,必须得标志是否访问过哦!并且为了防止某个节点多次入队,需要在其入队之前就将其设置成已访问!
作者:sweetiee
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
广度优先搜索,队列 多root
def BFS_solution1(root: Node):
if not root: return [], 0
遍历图
For r in range( rows ):
For c in range( cols ):
找到所有的root,加到queue中
layer = 0
queue = collection.deque([root])
while len(queue) != 0:
要实现层次遍历的时候才需要for ,注意此处,就算下面对queue进行了append操作(在for循环中),也不影响当前的len(queue)值,len(queue)只保存当前层次的节点个数。这也是能实现BFS的关键。
for i in range(len(queue)):
pop = queue.popleft() 取出队首元素
res[layer].append(pop.val) 将新元素加入队尾
if pop.left: queue.append(pop.left)
if pop.right: queue.append(pop.right)
遍历完一层才结束
layer += 1
res.append([])
return res[:-1], layer
做题总结:
第一步:画出树形图:
深度优先遍历
树上的每个节点:求解问题的不同阶段。叶子节点代表着当前子问题解决完成
状态变量
|
|
|
---|---|---|
depth | 遍历到第几层,一般作为递归的终止条件:depth == len(input) | 2 |
path | 已经选了哪些数 | 【1,3】 |
options | 当前阶段哪些数可以选(空间换时间) | 【2】 |
然后每一步都要记得状态回退
同时递归中path共用一个变量,在向result中添加数据的时候,需要浅拷贝path中的值
46.全排列
https://leetcode-cn.com/problems/permutations/
|
22.括号生成
https://leetcode-cn.com/problems/generate-parentheses/
|
93.复原IP地址
https://leetcode-cn.com/problems/restore-ip-addresses/
17.电话号码的字母组合
https://leetcode-cn.com/problems/letter-combinations-of-a-phone-number/
|