ツリーの 2 つの走査からバイナリ ツリーを構築する

トピック

2 つの整数配列が与えられ 、 ここで は  バイナリ ツリーの事前順序トラバーサル、 は 同じツリーのインオーダー トラバースであるとすると、バイナリ ツリーを構築し、そのルート ノードを返します。 preorderinorder preorderinorder

例 1:

入力: preorder = [3,9,20,15,7]、inorder = [9,3,15,20,7]
出力: [3,9,20,null,null,15,7]

例 2:

入力: preorder = [-1]、inorder = [-1]
出力: [-1]

ヒント:

  • 1 <= preorder.length <= 3000
  • inorder.length == preorder.length
  • -3000 <= preorder[i], inorder[i] <= 3000
  • preorder繰り返しinorder  要素はありませ ん 
  • inorder どちらも登場するのは、 preorder
  • preorder  バイナリ ツリーのプリオーダー トラバーサル シーケンスであることが保証されます。
  • inorder  二分木の順序走査シーケンスであることが保証される

前提知識: 

preorder : プレオーダー トラバーサル (プレオーダー トラバーサルはプレオーダー トラバーサルとも呼ばれます) - ルート ノードにアクセスします ---> ルートの左側のサブツリー ---> ルートの右側のサブツリーにアクセスします。

inorder:Inorder Traversal (Inorder Traversal) - ルートの左側のサブツリー ---> ルート ノード ---> ルートの右側のサブツリー

事前順序走査によって取得された最初のノードはルート ノードであるため、これを使用して、順序どおりの走査におけるルート ルート ノードの位置を決定できます。

次に、順序トラバーサルに従って、ルート ルート ノードの左側がこのバイナリ ツリーの左ツリーとなり、ルート ルート ノードの右側がこのクラス バイナリ ツリーの右ツリーとなり、このクラス バイナリ ツリーが構築されます。

トピックの理解を説明する例として例 1 を取り上げます。

入力例 1 : preorder = [3,9,20,15,7]、inorder = [9,3,15,20,7]

preorder = [   3 , 9, 20, 15, 7 ]    3 は、このバイナリ ツリーのルート ノードです

inorder = [  9 ,   3 15, 20, 7   ] 9 はルートの左側のツリーであり、ノードは 1 つだけなので、9 はルートの左側のノードです

3 つのノード 15、20、および 7 はルートの右のツリーであり、中間の順序に従ってルートの左のサブツリー ---> ルート ノード ---> ルートの右のサブツリーをたどります。

ルートの右ノードはノード 20 、ノード 20 の左ノードはノード 15 右ノードはノード 7 です。

上記のテキストの説明を示すために絵を描いてください


問題解決のアイデア:

タイトルで指定された事前順序トラバーサルのノード順序に従って、順序トラバーサルで再帰してバイナリ ツリーを構築します

1. 事前順序トラバーサルに従って、順序トラバーサルのルート ノード iRoot の位置を見つけ、ルート ノードを作成し、iBegin、iEnd、i++ の位置を決定します。

2. iBegin と iEnd の位置を判断し、iBegin>iEnd の場合は null を返し、再帰はロールバックを開始します。

2. インオーダートラバーサルでは、iRoot、iBegin、および iEnd の位置に従って、左側のツリーと右側のツリーを構築します。

上記の 3 つのステップを再帰し、再帰が完了するとバイナリ ツリーが構築され、ルート ノードの root に戻ります。

注: 事前順序トラバーサルによって取得されたノードの使用は、この質問のコードの核心です。

グラフィック:


問題解決コード

class Solution {
    public int i = 0;

    public TreeNode buildTree(int[] preorder, int[] inorder) {
        return create_a_binary_tree(preorder, inorder, 0, inorder.length - 1);
    }

    public TreeNode create_a_binary_tree(int[] preorder, int[] inorder, int inBegin, int inEnd) {
        if (inBegin > inEnd) {
            return null;
            //给定的数组int[] preorder, int[] inorder,遍历完了,没有子树了,该节点为空节点,返回null,递归开始回退
        }
        //先根据先序遍历创建根节点
        TreeNode root = new TreeNode(preorder[i]);
        //找到当前根节点,在中序遍历的位置
        int rootIndex = findIndex(inorder, inBegin, inEnd, preorder[i]);
        i++;
        //递归构建左树
        root.left = create_a_binary_tree(preorder, inorder, inBegin, rootIndex - 1);
        //递归构建右树
        root.right = create_a_binary_tree(preorder, inorder, rootIndex + 1, inEnd);
        //前序遍历完成,返回根节点
        return root;
    }

    private int findIndex(int[] inorder, int inBegin, int inEnd, int key) {
        for (int j = inBegin; j <= inEnd; j++) {
            if (inorder[j] == key) {
                return j;
            }
        }
        return -1;
    }
}

演算結果

トピックリンク

https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/submissions/

1 つ持ち上げて 3 つひっくり返して、もう 1 つ行う

ツリーの順序トラバーサルとポストオーダートラバーサルに基づいてバイナリ ツリーを構築する

2 つの整数配列が与えられ inorder 、 が  バイナリ ツリーのインオーダー トラバースと  同じツリーのポストオーダー トラバースである場合、このバイナリ ツリーを構築して返し postorder て ください 。inorderpostorder

例 1:

入力: inorder = [9,3,15,20,7]、postorder = [9,15,7,20,3]
出力: [3,9,20,null,null,15,7]

例 2:

入力: inorder = [-1]、postorder = [-1]
出力: [-1]

ポストオーダー トラバーサル (ポストオーダー トラバーサル) - ルートの左側のサブツリー ---> ルートの右側のサブツリー ---> ルート ノード。
ルートノードを作成したら、最初に右側の番号を作成し、次に左側のツリーを作成します

例 1 に従って説明すると、次の図はコードの再帰処理です。

コードの再帰により、バイナリ ツリーを構築するプロセス 

 問題解決コード

public class Solution {
    public int i = 0;

    public TreeNode buildTree(int[] inorder, int[] postorder) {
        i = postorder.length - 1;
        return create_a_binary_tree(postorder, inorder, 0, inorder.length - 1);
    }

    public TreeNode create_a_binary_tree(int[] postorder, int[] inorder, int inBegin, int inEnd) {
        if (inBegin > inEnd) {
            return null;
            //给定的数组int[] postorder, int[] inorder,遍历完了,没有子树了,该节点为空节点,返回null,递归开始回退
        }
        //先根据先序遍历创建根节点
        TreeNode root = new TreeNode(postorder[i]);
        //找到当前根节点,在中序遍历的位置
        int rootIndex = findIndex(inorder, inBegin, inEnd, postorder[i]);
        i--;
        //递归先构建右树
        root.right = create_a_binary_tree(postorder, inorder, rootIndex + 1, inEnd);
        //递归后构建左树
        root.left = create_a_binary_tree(postorder, inorder, inBegin, rootIndex - 1);
        //前序遍历完成,返回根节点
        return root;
    }

    private int findIndex(int[] inorder, int inBegin, int inEnd, int key) {
        for (int j = inBegin; j <= inEnd; j++) {
            if (inorder[j] == key) {
                return j;
            }
        }
        return -1;
    }
}

演算結果

トピックリンク:

https://leetcode.cn/problems/construct-binary-tree-from-inorder-and-postorder-traversal/submissions/

完结撒花✿✿ヽ(°▽°)ノ✿✿

おすすめ

転載: blog.csdn.net/m0_73740682/article/details/132308710