Articles

Code Challenge:Swiftでバイナリツリーのアルゴリズムを理解する

Challenge:*空でない*バイナリツリーが与えられた場合、最大パス合計を見つけます。 この問題では、パスは、いくつかの開始ノードから親子接続に沿ったツリー内の任意のノードまでのノードのシーケンスとして定義されます。 パスには少なくとも一つのノードが含まれていなければならず、ルートを通過する必要はありません。

Example #1:
Input:
4
/ \
5 6
Output: 15

例2:


Input:
-10
/ \
9 20
/ \
15 7
Output: 42

チャレンジ

名前が示すように、バイナリツリーはツリーベースのデータ構造の一般的なタイプです。 時間と空間の効率をサポートするために、ツリーは多くの場合、次の構造に似たキーと2つ以上のリーフノードで表されます:

Binary Search Tree

Trie Data Structure

As one may guess, recursion is also a common property of tree-based structures. ほとんどの再帰関数は実際のアプリケーションでは眉をひそめていますが、各リーフノードは別のツリーを表すこともできるため、ツリーは一定の効率をfigcaption>binary tree:強調表示された要素は、ルートノードと同様に子リーフノードとして機能します。

正しく理解されていない場合、ツリーは混乱につながるだけでなく、複雑さを追加することができます。 コードの課題を解決するには、ツリーをナビゲートするための一貫した方法と、可能なすべての順列を比較する方法を考案する必要があります。

アイデアをコードにコミットする前に、アイデアを視覚化してみましょう。 開始するには、まずツリーをナビゲートする方法について説明します。 ツリーベースの構造には*depth*の追加のコンセプトプロパティが組み込まれているため、高速列挙のような単純な手法は通常は適用されません。 代わりに、深さや幅優先検索(それぞれDFSとBFSなど)のような特定のトラバーサルアルゴリズムを使用することができます。 BFSのトピックは新しい議論のために十分に詳述されていますが、これはそのような構造を横断する通常の方法であると結論づけることができます。 ただし、バイナリツリーを使用しているため、特定のアルゴリズム効率を適用して、トラバーサルプロセスを短縮することができます。

では、二分木とは何ですか? 基本的には、ツリーとして視覚化される標準配列です。 この場合、構造をどのようにナビゲートするかに影響するため、視覚化の側面に重点が置かれます。 たとえば、各ノードについて、その左と右の葉の子ノードは、実際には次の単純な式を使用して計算できます。

説明したように、これらの式は、ツリーの基になる構造が配列であるために機能します。 これは、モデルを表すために特定のカスタムデータ構造を適用するBツリー、トライ、またはグラフのような他の構造とは異なります。

比較を行う

バイナリツリーは実際には配列に過ぎないので、基本的な列挙を使用してすべての値を反復処理することができます。 ただし、式を適用して子リーフノードを決定します。 確立されると、簡単な形式のメモ化を使用して、各サブツリーの合計を追跡できます(例: 動的プログラミング)。