筆記試験用の手書きコードに対応する深さ優先アルゴリズムと幅優先アルゴリズムを準備するには?
1. 深さ優先アルゴリズムとは? 幅優先アルゴリズムとは何ですか?
このような高位の名前は困惑した顔のように聞こえますか? 心配しないで, 私はあなたに人気のある例を挙げます. 「ママを探している小さなオタマジャクシ」の話を読んだかどうかはわかりません. 今私は使用します.この例は、全員に説明します。
私が下に描いた絵は醜いですが、見ることができます。
上の小さなオタマジャクシは位置 0 にあり、母親を見つけたい場合は最後の階に現れる可能性があります。
幅優先探索であれば、オタマジャクシは各層に応じてパスを見つけることができ、最終的に探索の結果は #0#1#2#3#4#5... になります。
深さ優先探索の場合、オタマジャクシは最後までルートをたどり、歩いた後に元の分岐点に戻り、別のパスを選択して最後まで歩き続けることができます。検索結果は #0#2#6#14#13#5#12#11#1#4#10…
(ps: 深さ優先アルゴリズムは DFS とも呼ばれ、幅優先アルゴリズムは BFS とも呼ばれます)
2. 幅優先アルゴリズムの使用シナリオ
1.連結ブロックの問題には、
グラフ、ツリー、2次元配列(行列)などが含まれます。つまり、点拡散によって連結ブロック全体を見つけることです。
2.階層トラバーサル
ツリーを与え、各レイヤーに従って出力します。
単純なグラフ (方向なし、重みなし) が与えられた場合、最短経路を見つけます。(実際には、グラフがトラバースしてノードを複製する可能性があることを除いて、ツリートラバーサルと同じです。毎回重複を削除するだけでよく、最終的にターゲットノードに最初に到達したときにレイヤーの数を取得します)。
3.トポロジーソーティング
現在の方向のグラフを与え、そのトポロジーソーティングを求めるか、トポロジーソーティングがあるかどうかを尋ねるか、最小のトポロジーソーティングを見つけるか、それが一意であるかどうかを尋ねます (本質は同じです)。古典的な質問は、特定のクラスを受講する前に別のクラスを受講する必要があるということです. 現在、いくつかのコースが与えられており、一部のコースは他のコースでオンラインにする必要があります. コースをどのように配置する必要があります. この時、被写体を描いて方向を付けると、トポロジーの問題です。
3. 幅優先アルゴリズムのテンプレート
class Solution {
public List<List<Integer>> levelOrder(TreeNode root) {
List<List<Integer>> res = new ArrayList<>();
if(root == null){
return res;
}
// 1. 定义队列
Queue<TreeNode> queue = new LinkedList<>();
// 2.加入初始条件
queue.offer(root);
// 3. 队列不为空的while循环
while(!queue.isEmpty()){
List<Integer> oneRes = new ArrayList<>();
int n = queue.size();
// 3.1 for循环将队列元素逐一取出进行处理
for(int i = 0;i < n;++i){
TreeNode temp = queue.poll();
// 3.0 业务处理
oneRes.add(temp.val);
// 3.2 将下一条件放入队列中
if(temp.left!=null){
queue.offer(temp.left);
}
if(temp.right!=null){
queue.offer(temp.right);
}
}
// 3.3 将符合条件的一种结果放入结果集中
res.add(oneRes);
}
// 4. 返回结果集
return res;
}
}
さらに、バイナリ ツリーのシリアル化と逆シリアル化は、幅優先アルゴリズムでも実装できます。タイトルで使用する方法を指定すると、幅優先アルゴリズムのシリアル化は、深さ優先アルゴリズムよりも直感的になります。
4. 深さ優先アルゴリズムの使用シナリオ
1. グラフまたはツリー トラバーサル (バイナリ ツリー トラバーサル、接続グラフなどを含む) (明らかなグラフまたはツリーではない場合もありますが、ツリーまたはグラフを自分で手動でシミュレートする必要があります)。
2.順列(いくつかの要素が与えられた場合、可能なすべての順列を返す)(たとえば、(1、2、3)、順列は(123)(132)(213)(231)(312)(321))。
3. 組み合わせ (いくつかの要素が与えられると、すべての可能な組み合わせを返す) (例: (1, 2, 3)、組み合わせは (空) (1) (2) (3) (12) (13) (23) (123 ) )。
順列や組み合わせを操作するとき, 繰り返しの結果につながる要素が繰り返されることがあります. HashSet を使用して重複を削除することに加えて, 代表を選択する方法を使用する方が適切です.繰り返される要素のうち、直接無視されます。
5. 深さ優先アルゴリズム テンプレート
//模板2
void dfs()//参数用来表示状态
{
if(到达终点状态){
...//根据题意添加
return;
}
if(越界或者是不合法状态)
return;
if(特殊状态)//剪枝
return ;
for(扩展方式){
if(扩展方式所达到状态合法){
修改操作;//根据题意来添加
标记;
dfs();
(还原标记);
//是否还原标记根据题意
//如果加上(还原标记)就是 回溯法
}
}
}
6. BFS と DFS の複雑さ
時間計算量は O(V+E)、V は頂点の数、E はエッジの数、
BFS の空間計算量はキュー サイズであり、幅に関連しています。
DFS の空間複雑度は、再帰を呼び出すときに占有される空間であり、深さに関連しています。
7. BFS と DFS の実装
BFS は通常、キューを介して実装されます。
DFS は通常、再帰によって実装されます。