Java 面接の必須テスト ポイント -- 講義 05: データ構造とアルゴリズム

このクラスのトピックはデータ構造とアルゴリズムです。業界では「プログラム = データ構造 + アルゴリズム」というよく言われた言葉があります。少し誇張されていますが、データ構造とアルゴリズムの重要性を説明するには十分です。このレッスンでは、次の 4 つの知識ポイントに焦点を当てます。

  1. 検索ツリーから B+ ツリーまで、ツリーに関連するデータ構造を説明します。

  2. 文字列マッチングに関する質問。

  3. アルゴリズムのインタビューで頻繁に調査される TopK の質問。

  4. アルゴリズムの問​​題に対するいくつかの一般的な問題解決方法。

データ構造の知識ポイント

まず、以下の図に示すように、データ構造の知識ポイントを見てみましょう。

  1. キューとスタックは頻繁に使用されるデータ構造なので、その特性を理解する必要があります。キューは先入れ先出しであり、スタックは後入れ先出しです。

  2. テーブルには、連続領域を占有する配列、ポインタによってリンクされた一方向および双方向のリンク リスト、端から端まで接続された循環リンク リスト、ハッシュ テーブル (ハッシュ テーブルとも呼ばれる) など、多くの種類があります。

  3. グラフは特定の分野でよく使用されます。たとえば、ルーティング アルゴリズムでよく使用されます。グラフは、有向グラフ、無向グラフ、重み付きグラフに分けられます。この部分では、グラフの深さトラバーサル アルゴリズムと幅トラバーサル アルゴリズムを習得し、最短経路を理解する必要があります。 .アルゴリズム。

  4. ツリーの内容。ツリーは通常、検索やソートのための補助構造として使用されます。残りの 2 つの部分はツリーに関連しており、1 つはバイナリ ツリー、もう 1 つはマルチフォーク ツリーです。

    1. マルチツリーには、ファイル検索に適した B ツリー、B+ ツリー、B* ツリーなどの B ツリー ファミリが含まれ、もう 1 つは文字列のマルチモード マッチングに適した辞書ツリーです。
    2. バイナリ ツリーには、データの検索と並べ替えに適したバランス バイナリ ツリー、赤黒ツリー、ハフマン ツリー、およびヒープが含まれます。このパートでは、バイナリ ツリーの構築、挿入、および削除操作の実装を理解し、バイナリ ツリーの事前順序、順序内、および順序後の走査を習得する必要があります。
アルゴリズムの知識ポイント

以下の図に示すように、アルゴリズム部分の知識ポイントの概要を見てみましょう。

  1. アルゴリズムの問​​題に対して一般的に使用される問題解決方法。

  2. 複雑さはアルゴリズムの品質を測る基準の 1 つであり、アルゴリズムの時間計算量と空間計算量の計算方法を習得する必要があります。時間計算量を計算する方法は、一般に、最も実行時間が長いステートメントを見つけ、次にステートメントの実行回数の桁数を計算し、最後に大文字の O を使用して結果を表します。

  3. 一般的に使用される文字列マッチング アルゴリズムと、さまざまなアルゴリズムのマッチングの考え方を理解します。

  4. ソートも頻繁に検討される知識ポイントです。ソート アルゴリズムは、挿入、交換、選択、マージ、基数の 5 つのカテゴリに分類されます。その中でも、クイック ソートとヒープ ソートが最も頻繁に検討されます。これらを習得するには、手書きアルゴリズムを実装できるようになります。

  5. 一般的に使用される検索アルゴリズムには、バイナリ サーチ、バイナリ ソート ツリー、B ツリー、ハッシュ、ブルーム フィルターなどが含まれます。これらの適用可能なシナリオを理解する必要があります。たとえば、バイナリ サーチは少数のセット メモリの検索に適しており、B ツリーは適しています。ファイルのインデックス作成にはハッシュ定数レベルの時間 Complexity が、高い検索効率が必要な場合に適しており、BloomFilter は大規模なデータセットのデータ存在フィルタリングに適しています。

二分探索木の詳しい説明
二分探索木

次の図に示すように、二分探索ツリーは、各ノードに値が含まれ、各ノードが最大 2 つのサブツリーを持つという条件を満たします。各ノードの左側のサブツリー ノードの値はそれ自体の値より小さく、各ノードの右側のサブツリー ノードの値はそれ自体の値より大きくなります。

バイナリ ツリーのクエリ時間の複雑さは log(N) ですが、ノードの挿入と削除が継続的に行われると、バイナリ ツリーの高さは増加し続ける可能性があります。バイナリ サーチ ツリーのすべてのノードが左側のサブツリーのみ、または右側のみを持つ場合サブツリー、ツリーの場合、検索パフォーマンスは線形に低下します。

バランスの取れた二分木

AVL ツリーのように、各ノードの左右のサブツリーの高さの差の絶対値が 1 を超えないようにするバランス バイナリ ツリーは、上記の問題を解決します。AVL ツリーは厳密にバランスのとれたバイナリ ツリーです。データを挿入または削除するときは、バランスを維持するために回転する必要がある場合があります。挿入と削除が比較的少ないシナリオに適しています。

赤黒い木

赤黒ツリーは、より実用的な非厳密なバランスの二分木です。赤黒ツリーは、全体的なバランスよりも局所的なバランスに注意を払い、どのパスも他のパスの 2 倍の長さにならないようにするため、バランスに近くなりますが、多くの不必要な回転操作が削減され、より実用的になります。前述したように、Java 8 の HashMap では、ハッシュ競合が発生した場合の検索問題を解決するために赤黒ツリーが使用されています。TreeMap では、秩序性を確保するために赤黒の木も使用します。

二分探索木の特徴に加えて、赤黒木には次の図に示すような規則もあります。

  1. 各ノードは赤または黒です。

  2. ルートノードは黒です。

  3. 各リーフ ノードは、図の黒い三角形などの黒い空のノードです。

  4. 赤いノードの両方の子ノードは黒です。

  5. 任意のノードからそのリーフ ノードまでのすべてのパスには、同じ数の黒いノードが含まれます。

Bツリーの詳しい説明
B ツリー

B ツリーはマルチツリーであり、マルチウェイ検索ツリーとも呼ばれます。B ツリーの各ノードは複数の要素を格納できるため、ファイル インデックスでの使用に非常に適しており、ディスク IO の数を効果的に削減できます。B ツリー内のすべてのノードの子ノードの最大数を B ツリーの次数と呼び、下図に示すように 3 次の B ツリーであり、2-3 ツリーとも呼ばれます。

m 次の B ツリーには次の特性があります。

  1. 非リーフ ノードには最大 m 個のサブツリーがあります。

  2. ルート ノードには少なくとも 2 つのサブツリーがあり、非ルート ノードと非リーフ ノードには少なくとも m/2 のサブツリーがあります。

  3. 非リーフ ノードに格納されているキーワードの数は、ノードのサブツリーの数 -1 に等しいです。つまり、ノードに 3 つのサブツリーがある場合、ノードには 2 つのキーワードが含まれている必要があります。

  4. 非リーフ ノードのキーワード サイズは順序どおりです。たとえば、上図の左側のノードの 2 つの要素 37 と 51 は順序通りです。

  5. ノード内の各キーワードについて、左側のサブツリーのキーワードはキーワードより小さく、右側のサブツリーのキーワードはキーワードより大きくなります。上の図に示すように、キーワード 51 の左側のサブツリーには 42 と 49 があり、どちらも 51 より小さく、右側のサブツリーには 59 個のノードがあり、51 より大きくなります。

  6. すべてのリーフ ノードは同じレベルにあります。

Bツリーでの検索は、ルートノードから開始し、ノード内の順序付けられたキーワード列に対して二分探索を実行し、見つかった場合は終了、見つからない場合は、その範囲のサブツリーに入ります。クエリキーワードが属し、リーフノードまで検索します。

結論は:

  • B ツリーのキーワードはツリー全体に分散されており、キーワードは 1 つのノードにのみ表示されます。

  • 検索は非リーフ ノードで停止する場合があります。

  • B ツリーは通常、ファイル システムで使用されます。

B+ ツリー

下の図は、B+ ツリーと呼ばれる B ツリーの変形です。

B+ ツリーの定義は基本的に B-tree と同じですが、以下の特徴が異なります。

  1. ノード内のキーワードの数はサブツリーの数と同じです。たとえば、ノードに 3 つのキーワードがある場合、サブツリーは 3 つあります。

  2. キーワードに対応するサブツリー内のノードはすべてキーワード以上であり、サブツリーにはキーワード自体が含まれます。

  3. すべてのキーワードはリーフ ノードに表示されます。

  4. すべてのリーフ ノードには、次のリーフ ノードへのポインタがあります。

B ツリーとは異なり、B+ ツリーは検索時に非リーフ ノードにヒットせず、確実にリーフ ノードをクエリします。一方、リーフ ノードはデータ ストレージ層に相当し、データ ストレージ層に対応するデータを保存します。一方、非リーフ ノードはキーワードのみを保存します。リーフ ノードへのポインタはキーワードに対応するデータを保存しません。そのため、キーワードを持つ非リーフ ノードの数が同じであれば、B+ ツリーは B ツリーよりもはるかに小さくなります。

B+ ツリーはインデックス システムに適しており、MySQL データベースのインデックスは B+ ツリーの実装を提供します。理由は 3 つあります。

  1. リーフ ノードを接続するポインターがあるため、B+ ツリーは範囲の取得により適しています。

  2. 非ページ ノードはキーワードとポインタのみを保存するため、非リーフ ノードと同じサイズであれば、B+ ツリーはより多くのキーワードを収容でき、ツリーの高さを減らし、クエリ中のディスクの読み取りと書き込みのコストを削減できます。

  3. B+ ツリーのクエリ効率は比較的安定しています。すべてのキーワード検索は、ルート ノードからリーフ ノードまでのパスをたどる必要があり、すべてのキーワード クエリのパス長は同じであり、効率も同等です。

最後に、B* ツリーのバリエーションもあり、B+ ツリーの非葉ノードには、同じ層内の次の非葉ノードへのポインタも追加されることを簡単に理解できます。

文字列マッチングの詳しい説明
文字列マッチングの問題

面接では、文字列関連の質問がアルゴリズム テストの質問としてよく使用されます。文字列一致の質問を見てみましょう。まず、面接でよく聞かれる質問「指定された文字列内の括弧が一致するかどうかを判断してください」を理解しましょう。

一般に、面接の質問の説明は比較的簡単なので、回答する前に質問の要件や詳細について面接官とさらにやり取りすることができます。この質問を例にとると、括弧の範囲、山括弧を含む大括弧、中括弧、小括弧のみを考慮するか、関数の入力パラメータと戻り値に要件があるか、面接官に確認できます。必要ですか? 大きなファイルの操作などを検討してください。

改良後のこの質問の要件は、大、中、小の括弧のみが考慮されること、大きなファイルの操作は考慮されないこと、文字列が入力パラメータとして使用されること、戻り値がブール型であること、括弧が存在しないことであると仮定します。も一致としてカウントされます。したがって、解決策は次のとおりです。

  • 文字一致の問題は、スタックの機能を使用して処理できます。

  • 左のブラケットが見つかるとスタックにプッシュされ、右のブラケットが見つかるとスタックからポップされて、ペアになっているブラケットかどうかを比較します。

  • 一致が完了したとき、スタックが空の場合は一致を意味し、そうでない場合は、左括弧が右括弧よりも多いことを意味します。

文字列コード

以下の図に示すように、実際の実装コードを見てみましょう。

上記の考え方によれば、文字列をトラバースする必要があるため、スタック操作のトリガー条件を最初に決定する必要があります。これは、プッシュとポップのマッチングを容易にするブラケットのペアを定義することです。ここで注意したいのは、変数名には明確な意味が必要であり、a や b など明確な意味のない変数名を安易に使用しないなど、コーディングを行う際のコーディングスタイルや仕様に注意する必要があります。

最初に括弧のマップを定義します。キーはすべての右括弧で、値は対応する左括弧です。この定義により、スタックをポップするときに括弧がペアであるかどうかを比較しやすくなります。

マッチング関数のロジックをもう一度見てみましょう。ここで注意すべき点は、ツールの機能として堅牢性の防御をしっかり行う必要があり、まず入力パラメータの null チェックが必要です。

次に、文字タイプを保存するスタックを定義し、入力文字列の走査を開始します。

現在の文字が括弧内の値、つまり左括弧の場合、その文字はスタックにプッシュされます。なお、map の値の問い合わせ方法は O(N) ですが、この問題では括弧の種類が非常に少ないため、コードを簡潔にするためにこの方法を使用しています。現在の文字が左括弧ではない場合は、containskey を使用してそれが右括弧であるかどうかを判断します。右括弧の場合は、一致するかどうかを確認する必要があります。スタックが空の場合は、右括弧の数が左括弧よりも多いことを意味します。スタックが空ではないが、左括弧がスタックから飛び出した場合は、一致します。一致しない場合、どちらの場合も文字列内の括弧が一致しないことを示します。

走査が完了すると、スタックに余分な左括弧が存在しない場合に一致します。

最後に強調したいのは、コーディングに関する質問では、プログラミングのアイデアに加えて、プログラミングのスタイルや詳細の扱いにも注意を払う必要があるということです。

文字列の問題解決のアイデア

次に、文字列一致問題の問題解決スキルをまとめてみましょう。

  • まず、不正解を避けるために質問を注意深く確認してください。まず、単一パターン マッチング問題であるか複数パターン マッチング問題であるか、および複数のヒット条件があるかどうかを判断できます。

  • 次に、アルゴリズムの時間計算量やメモリ使用量に関して追加の要件があるかどうかを判断します。

  • 最後に、ヒット結果が複数ある場合、最初にヒットしたものを返すのか、それとも全てを返すのかなど、期待する戻り値を明確にする必要があります。

問題解決のアイデアについて。

  • 単一のパターン マッチング問題の場合は、BM または KMP アルゴリズムの使用を検討できます。

  • マルチモードマッチングの場合は、タイヤツリーの使用を検討してください。

  • マッチング アルゴリズムを実装するときは、プレフィックス マッチングまたはサフィックス マッチングの使用を検討できます。

  • 最後に、問題の解決にスタック、バイナリ ツリー、マルチツリーなどのデータ構造を使用できるかどうかを検討できます。

一般的な文字列シングルモードおよびマルチモードマッチングアルゴリズムの処理概念を理解することをお勧めします。

TopKの詳しい説明
トップKの質問

TopK問題は実際のビジネスでよく起こる代表的な問題で、例えばWeiboの人気ランキングもTopK問題に属します。

TopK は通常、N 個の数値セット内の最小または最大の K 値を見つけるために必要ですが、通常、N は非常に大きくなります。TopK はソートによって解決できますが、時間の計算量は高く、通常は O(nk) です。ここでは、より効率的な方法を見ていきます。

以下の図に示すように、最初に最初の K 要素を取得して大きなルート ヒープを構築し、次に残りの NK 要素を走査します。それがヒープの先頭の要素より小さい場合は、ヒープの先頭の要素を置き換えます。そしてヒープを調整します。すべての走査が完了すると、ヒープ内の K 要素は最小の K 値になります。

このアルゴリズムの時間計算量は N*logK です。このアルゴリズムの利点は、メモリ内のすべての要素を読み取る必要がなく、非常に大規模なデータ セットに適用できることです。

TopK バリアントの問題

TopK バリアントの問題は、N 個の順序付けされたキューから最小または最大の K 値を見つけることです。この問題は、複数のデータ セットを並べ替えているという点で異なります。初期データセットは順序付けされているため、N 個のキュー内のすべての要素を走査する必要はありません。したがって、問題解決のアイデアは、横断する要素をいかに減らすかということになります。

問題解決の考え方を下図に示します。

  1. 最初のステップは、N 個のキューの先頭要素、つまり各キューの最小要素を使用して、K 個の要素を持つ小さなルート ヒープを形成することです。やり方はTopKと同じです。

  2. 2 番目のステップは、すべてのキューの最小要素であるヒープの最上位値を取得することです。

  3. 3 番目のステップは、ヒープの最上位要素がヒープの最上位に配置されるキューに次の値を入れてから、ヒープを調整することです。

  4. 最後に、十分な K 数が得られるまでこの手順を繰り返します。

ここにも小さな最適化があります。3 番目のステップでヒープの先頭に新しい値を追加するときに、それをヒープの最大値と比較します。すでにヒープの最大値より大きい場合、ループは早期に終了される。このアルゴリズムの時間計算量は (N+K-1)*logK です。これはキューの長さとは関係がないことに注意してください。

一般的に使用されるアルゴリズムの詳細な説明

アルゴリズムに関する知識は数多くあり、アルゴリズムの問​​題解決能力を高めるには、問題を適切にブラッシュアップする必要がありますが、問題をブラッシュアップするだけで問題を解決できるわけではありません。刻々と変化する状況に直面しても変わらないためには、一般的に使用される問題解決のアイデアや方法をいくつかマスターする必要があります。一般的に使用される 5 つのアルゴリズムの問​​題解決手法 (分割統治、動的プログラミング、貪欲、バックトラッキング、分岐定義) について説明し、それらがどのようなシナリオに適しているか、またそれらをどのように適用するかを見てみましょう。

分割統治

分割統治法の考え方は、直接解決することが困難な複雑または大規模な問題を、多数の小さな同一の問題に分割し、分割統治することです。たとえば、クイック ソート、マージ ソートなどはすべて分割統治法を適用します。

分割統治法の使用に適したシナリオは、次の 3 つの要件を満たす必要があります。

  1. サブ問題に分解できます。

  2. 部分問題の解決策は、元の問題の解決策に組み合わせることができます。

  3. サブ質問は互いに関連しません。

分割統治法を使用して問題を解決するための一般的な手順を次の表に示します。

  1. 最初のステップは、最小限の部分問題の解決策を見つけることです。

  2. 2 番目のステップは、部分的な問題に対する解決策を組み合わせる方法を見つけることです。

  3. 3 番目のステップは、再帰の終了条件を見つけることです。

動的プログラミング

動的プログラミングも、分割統治法と同様に、問題を複数の部分問題に分解します。分割統治法とは異なり、部分問題の解決策は関連しています。前者の副問題の解決策は、後者の副問題の解決に役立つ情報を提供します。動的計画法では、各部分問題を順番に解決します。各部分問題を解決するときに、すべての局所解がリストされ、大域最適に到達する可能性が高い局所解が意思決定を通じて保持されます。最後の部分問題の解決策は、最初の問題の解決策です。

動的プログラミングを使用するシナリオは、次の 3 つの条件を満たす必要があります。

  1. サブ問題は順番に解決する必要があります。

  2. 隣接するサブ問題間には相関関係があります。

  3. 最後の部分問題の解決策は、最初の問題の解決策です。

上の表の 2 行目に示すように、動的プログラミングを使用して問題を解決する場合。

  1. 最初のステップは、最適解の特性を分析することです。

  2. 2 番目のステップは、最適なソリューションを再帰的に定義することです。

  3. 3 番目のステップは、さまざまな段階での最適値を記録することです。

  4. 4 番目のステップは、ステージ最適解に基づいて大域最適解を選択することです。

貪欲なアルゴリズム

3 番目の貪欲アルゴリズムは、局所的な最適解を考慮するため、すべての問題に対して全体的な最適解を得ることができません。貪欲アルゴリズムの鍵は、貪欲戦略の選択です。貪欲戦略には後遺症があってはなりません。これは、特定の状態の後のプロセスは前の状態に影響を与えず、現在の状態にのみ関連することを意味します。

貪欲アルゴリズムで使用されるシナリオは、次の 2 つの点を満たしている必要があります。

  1. 局所最適解は大域最適解を生み出すことができます。

  2. それは、今私が言ったことは、後遺症があってはならないということです。

以下の図に示すように、貪欲アルゴリズムを使用して問題を解決するための一般的な手順は次のとおりです。

  1. 最初のステップは、それをサブ問題に分解することです。

  2. 2 番目のステップは、貪欲戦略に従って各部分問題の局所的な最適解を計算することです。

  3. 3 番目のステップは、局所的な最適解をマージすることです。

バックトラッキングアルゴリズム

バックトラッキングアルゴリズムは、実際には最適な選択条件に従って前方に探索する深さ優先探索アルゴリズムであり、探索が一定のステップに達すると、元の選択が最適ではない、または目的を達成できないことがわかり、元の選択に戻ります。前のステップに戻って新しい選択をする、できなかったときに戻ってやり直す方法がバックトラック法です。

バックトラッキング法は、迷路問題など、深さ優先探索が可能で、解空間のすべての解を取得する必要がある状況に適しています。

上の図に示すように、バックトラッキング手法の一般的な問題解決手順は次のとおりです。

  1. 最初のステップは、与えられた問題の解空間を決定することです。

  2. 2 番目のステップは、ノードの拡張検索ルールを決定することです。

  3. 3 番目のステップでは、深さ優先の方法で解空間を検索し、プルーニング関数を使用して検索プロセス中の無効な検索を回避します。

分岐方法

最後に、分岐限定法があります。これには、バックトラッキング法とは異なる解決目標があります。バックトラッキング法の目標は制約を満たすすべての解を見つけることですが、分岐限定法の目標は制約を満たす解を見つけることです。

分枝限定法は、幅優先探索や、整数計画問題を解く場合など、解空間内の任意の解を取得するだけで十分な場合に適しています。

上の図に示すように、分岐限定法の一般的な問題解決手順は次のとおりです。

  1. 最初のステップは、ソリューションの特性を判断することです。

  2. 2 番目のステップは、先入れ先出し、先入れ後出しなどの子ノードの検索戦略を決定することです。

  3. 3 番目のステップは、幅優先トラバーサルによって解決策を見つけることです。

点検ポイントとボーナスポイント
検査箇所

以上がデータ構造とアルゴリズムの内容に焦点を当てた要点です。次に、面接官の観点から、面接に関連するポイントを要約します。

  1. データ構造にどのようなバイナリ ツリーがあり、それらのツリーがどのような特性を持っているかなど、基本的なデータ構造と特性を理解します。

  2. テーブル、スタック、キュー、ツリーに精通しており、さまざまなタイプの実装の使用シナリオを深く理解している必要があります。たとえば、赤黒ツリーは検索に適しており、B+ ツリーはインデックス作成に適しています。

  3. 一般的に使用される検索アルゴリズムと並べ替えアルゴリズム、およびその複雑さと安定性を理解する。特に、クイック ソートとヒープ ソートの実装を習得する必要があります。

  4. 一般的に使用される文字列処理アルゴリズムと処理の考え方を理解する必要があります。たとえば、BM アルゴリズムは文字列マッチングにサフィックス マッチングを使用します。

  5. アルゴリズム実装の複雑さ、特に TopK 問題の時間計算量計算などの時間計算量を分析できるようになります。

  6. よく使われる5つの問題解決方法、問題を解決するための考え方と解決すべき問題の種類、および問題を解決する手順を理解する必要があります。

ボーナス

アルゴリズム関連の質問で面接官から追加点を得るには、次の点に留意してください。

  1. データ構造と実際の使用シナリオを組み合わせる機能。たとえば、赤黒ツリーを導入する場合は TreeMap の実装と組み合わせ、B+ ツリーを導入する場合は MySQL のインデックス実装と組み合わせます。

  2. 一般的な並べ替えにおける TopK アルゴリズムの応用など、ビジネス シナリオにおけるさまざまなアルゴリズムの応用を知ることができます。

  3. 曖昧な質問に対して積極的にコミュニケーションを図り、条件や境界線を確認する能力(例えば、先ほど紹介した括弧書き問題の内容を面接官に再確認するなど)。

  4. アルゴリズム コードを作成する前に、書き始めてすぐに頭を埋めて書くのではなく、まず問題解決のアイデアについて話します。通常、問題解決のアイデアに問題がある場合、面接官は適切な指導を行います。

  5. ソリューション内のいくつかの問題を発見し、改善のためのアイデアを与えることができます。たとえば、面接では時間の制約があるため、全員がより保守的な問題解決のアイデアを選択する可能性がありますが、それが必ずしも最適な解決策であるとは限りません。この場合、回答後に現在のアルゴリズムやアイデアの問題点を指摘することができます。改善のために。たとえば、ソリューションのパフォーマンスを向上させるためにマルチスレッドの使用を検討できます。

実際の質問のまとめ

最後に、実際の面接でよくある質問を見てみましょう。前半の要約は次のとおりです。

  • 問題 1 と 2 はすべて基本的なアルゴリズムであり、しっかりとマスターする必要があります。一部の問題では、ツリー トラバーサル、クイック ソートなど、再帰と非再帰の実装を覚える必要があります。

  • 質問 5 のようなメモリの使用を制限する質問の場合は、分割統治の考え方を使って分解することを検討してください。

  • 質問 6: 配列の重複排除はソートまたはハッシュ化できます。

実際の質問の後半部分は次のように要約されます。

  • 質問 9: イディオム ソリティア。これを解くために深さ優先検索を使用することを検討できます。

  • 質問 10: 2 つのノードの共通の祖先を見つけるには、再帰的と非再帰的という 2 つの方法を検討できます。

このクラスは基礎知識の学習モジュールを完了し、次のクラスでは応用知識モジュールとその主題の共通ツールセットの説明が始まります。

おすすめ

転載: blog.csdn.net/g_z_q_/article/details/129826265