当前位置: 首页 > 知识库问答 >
问题:

对于给定按序和按序遍历的二叉树,如何推导该公式的证明,以获得正确的子树?

董阳平
2023-03-14

我在看leetcode上的这个问题。给定两个数组,按序和按序,需要构造一个二叉树。我得到了问题的通解。

预排序遍历访问根、左和右,因此左子级将是当前预排序节点索引1。根据该值,您可以使用inorder数组知道树左侧有多少个节点。在答案中,用于找到合适孩子的公式是“preStart inIndex-inStart 1”。

我不想记住这个公式,所以我想知道是否有证据证明这一点?我浏览了那里的讨论板,但仍然缺少一个链接。

共有1个答案

杭曦
2023-03-14

>

  • 在Python中,我们还可以使用pop(0)来解决这个问题,尽管这效率很低(但它会通过)。

    为了降低效率,我们可以将deque()popleft()一起使用,但是不能在LeetCode上使用,因为我们无法控制树。

    class Solution:
        def buildTree(self, preorder, inorder):
            if inorder:
                index = inorder.index(preorder.pop(0))
                root = TreeNode(inorder[index])
                root.left = self.buildTree(preorder, inorder[:index])
                root.right = self.buildTree(preorder, inorder[index + 1:])
                return root
    

    对于Java和C来说,就像你说的那样(没有证据),这会有点不同,但这篇文章可能会有点帮助:

    public class Solution {
        public static final TreeNode buildTree(
            final int[] preorder,
            final int[] inorder
        ) {
            return traverse(0, 0, inorder.length - 1, preorder, inorder);
        }
    
        private static final TreeNode traverse(
            final int preStart,
            final int inStart,
            final int atEnd,
            final int[] preorder,
            final int[] inorder
        ) {
            if (preStart > preorder.length - 1 || inStart > atEnd) {
                return null;
            }
    
            TreeNode root = new TreeNode(preorder[preStart]);
            int inorderIndex = 0;
    
            for (int i = inStart; i <= atEnd; i++)
                if (inorder[i] == root.val) {
                    inorderIndex = i;
                }
    
            root.left = traverse(preStart + 1, inStart, inorderIndex - 1, preorder, inorder);
            root.right = traverse(preStart + inorderIndex - inStart + 1, inorderIndex + 1, atEnd, preorder, inorder);
            return root;
        }
    
    }
    
    // The following block might slightly improve the execution time;
    // Can be removed;
    static const auto __optimize__ = []() {
        std::ios::sync_with_stdio(false);
        std::cin.tie(nullptr);
        std::cout.tie(nullptr);
        return 0;
    }();
    
    // Most of headers are already included;
    // Can be removed;
    #include <cstdint>
    #include <vector>
    #include <unordered_map>
    
    using ValueType = int;
    
    static const struct Solution {
            TreeNode* buildTree(
                std::vector<ValueType>& preorder,
                std::vector<ValueType>& inorder
            ) {
                std::unordered_map<ValueType, ValueType> inorder_indices;
    
                for (ValueType index = 0; index < std::size(inorder); ++index) {
                    inorder_indices[inorder[index]] = index;
                }
    
                return build(preorder, inorder, inorder_indices, 0, 0, std::size(inorder) - 1);
            }
    
        private:
            TreeNode* build(
                std::vector<ValueType>& preorder,
                std::vector<ValueType>& inorder,
                std::unordered_map<ValueType, ValueType>& inorder_indices,
                ValueType pre_start,
                ValueType in_start,
                ValueType in_end
            ) {
                if (pre_start >= std::size(preorder) || in_start > in_end) {
                    return nullptr;
                }
    
                TreeNode* root = new TreeNode(preorder[pre_start]);
                ValueType pre_index = inorder_indices[preorder[pre_start]];
                root->left = build(preorder, inorder, inorder_indices, pre_start + 1, in_start, pre_index - 1);
                root->right = build(preorder, inorder, inorder_indices, pre_start + 1 + pre_index - in_start, pre_index + 1, in_end);
                return root;
            }
    };
    

  •  类似资料:
    • 如果我们要在左子树中找到节点,甚至在根节点上,它会给出正确的输出,但是如果我们在右边找到任何节点,比如根->right,即节点70,它会给出错误的输出20、30、40、50、60。我知道我在哪里犯了错误,我应该如何修改代码,这样对于输入70,只有它的左子树,即,节点60是打印的。

    • 我在研究一个重建二叉查找树的函数。我正试着先用手做。 说我有:pre-10,3,5,4,15,7,8,2,9,20 in-4,5,3,15,10,20,8,7,9,20 我弄不明白。我知道10必须是根,顺序序列中10左边的所有数字都必须在右边的子树中。 那会给我 4,5,3,15 15大于10,并且为了成为二叉查找树,左子树中的所有节点应该小于根。 这是否意味着这两个序列形成了一个无效的二叉搜索树

    • 为了上课,我必须创建一个状态对象的二叉树,每个状态对象包括一个居民对象的二叉树,这些居民对象组织住在每个州的人。我试图在一个给定的州中搜索最老的居民;然而,居民是按字母顺序组织在树中的,这对我的搜索毫无帮助。因此,我必须遍历整个居民树,更新保存最老的人的节点,并在树被完全遍历后返回它。我已经有了代码的第一部分,但是还停留在如何写递归的剩余部分。 状态树的方法: 然后是公共“包装器”状态树方法:

    • 中序遍历二叉树 按完全二叉树的层次遍历给出一棵二叉树的遍历序列(其中用0表示虚结点),要求输出该二叉树的深度及中序遍历该二叉树得到的序列。 输入格式: 首先输入一个整数T,表示测试数据的组数,然后是T组测试数据。每组测试数据首先输入一个正整数n(n≤1000),代表给出的二叉树的结点总数(当然,其中可能包含虚结点)。结点编号均为正整数,且各不相同。 然后输入n个正整数,表示按完全二叉树(即第1层1

    • 我试图使用队列的链表实现实现二叉搜索树的级别顺序遍历。 我已经检查了二叉查找树的实现,它是好的。队列的链表实现也是正确的。在这里,我试图访问节点并将其子节点排队。然后使用弹出函数实际访问节点。 这最终是通过递归调用完成的。当我运行以下代码时,我以不同的顺序获得输出。

    • 我想对二叉树执行级别顺序遍历。因此,对于给定的树,说: 产出将是: 我知道我可以使用某种队列,但在C中递归地实现这一点的算法是什么?感谢您的帮助。