LeetCode //C - 106. インオーダーおよびポストオーダートラバーサルからバイナリツリーを構築する

106. インオーダーおよびポストオーダートラバーサルからバイナリツリーを構築する

2 つの整数配列inorderpostorder (inorder はバイナリ ツリーの順序トラバーサル、postorder同じツリーのポストオーダー トラバース) が与えられた場合、バイナリ ツリーを構築して返します。
 

例 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 <= inorder.length <= 3000
  • postorder.length == inorder.length
  • -3000 <= inorder[i]、postorder[i] <= 3000
  • inorder と postorder は一意の値で構成されます。
  • postorder の各値は inorder にも表示されます。
  • inorder はツリーの順序走査であることが保証されます。
  • postorder は、ツリーの postorder 走査であることが保証されます。

From: LeetCode
Link: 106. インオーダーおよびポストオーダートラバーサルからバイナリツリーを構築する


解決:

アイデア:
  1. 通信販売の横断的洞察:
  • ポストオーダー トラバーサルでは、最後の要素は常にツリー (またはサブツリー) のルートになります。
  1. インオーダートラバーサルインサイト:
  • インオーダートラバーサルでは、(ポストオーダートラバーサルから) ルートを見つけると、インオーダーリスト内のルートの左側にあるものはすべて左サブツリーとなり、右側にあるものはすべて右サブツリーになります。

これらの洞察を踏まえて、段階的なアプローチを次に示します。

  1. まず、ポストオーダー リストの最後の要素を使用してツリーのルートを特定します。
  2. 順序リストでこのルートを検索して、左右のサブツリー間の境界を決定します。
  3. 上記の手順を左と右のサブツリーに再帰的に適用します。
  • 左側のサブツリーの場合: ルートより前の inorder リストの部分と、postorder リストの対応する要素を使用します。
  • 右側のサブツリーの場合: inorder リストのルート以降の部分と、postorder リストの対応する要素を使用します。
  1. inorder リストの開始インデックスが終了インデックスより大きい場合、再帰を停止します。

関数 build は、ツリーを構築する再帰的なヘルパー関数です。考慮すべき順序リストの現在の境界 (開始インデックスと終了インデックス) を受け入れます。また、再帰呼び出しごとにデクリメントされる、ポストオーダー リスト内の現在のインデックスへのポインターも受け入れます。

関数 buildTree は、ツリーの構築を開始するメイン関数です。postorder インデックスを最後の要素に設定し、build 関数を呼び出すことでプロセスが開始されます。

コード:
/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     struct TreeNode *left;
 *     struct TreeNode *right;
 * };
 */
struct TreeNode* build(int* inorder, int inStart, int inEnd, 
                       int* postorder, int* postIndex) {
    
    
    // Base condition
    if (inStart > inEnd) return NULL;

    // Allocate memory for the new node
    struct TreeNode* node = (struct TreeNode*)malloc(sizeof(struct TreeNode));
    
    // The current postIndex is the value of the root for this subtree
    node->val = postorder[*postIndex];
    node->left = NULL;   // Initialize left child to NULL
    node->right = NULL;  // Initialize right child to NULL
    (*postIndex)--;

    // If there's no left or right children, return the node
    if (inStart == inEnd) return node;

    // Find the index of the current node in inorder to split left and right subtree
    int inIdx;
    for (inIdx = inStart; inIdx <= inEnd; inIdx++) {
    
    
        if (inorder[inIdx] == node->val) break;
    }

    // Recursively build the right and then the left subtree
    node->right = build(inorder, inIdx + 1, inEnd, postorder, postIndex);
    node->left = build(inorder, inStart, inIdx - 1, postorder, postIndex);

    return node;
}

struct TreeNode* buildTree(int* inorder, int inorderSize, int* postorder, int postorderSize) {
    
    
    // Start from the end of postorder (which represents the root of the tree)
    int postIndex = postorderSize - 1;
    return build(inorder, 0, inorderSize - 1, postorder, &postIndex);
}

おすすめ

転載: blog.csdn.net/navicheung/article/details/132722795
おすすめ