在给定有序和预序遍历的情况下,如何导出该公式的证明以使二叉树成为正确的子代? 仅适用于Python C ++

问题描述

我正在看leetcode上的这个question。给定两个数组,即有序和预排序,您需要构造一个二叉树。我得到了问题的一般解决方案。

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

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

解决方法

仅适用于Python

  • 在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 ++,这就像您所说的(没有证据)有些不同,但是也许this post会有所帮助:

public class Solution {
    public static final TreeNode buildTree(
        final int[] preorder,final int[] inorder
    ) {
        return traverse(0,inorder.length - 1,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,inorder);
        root.right = traverse(preStart + inorderIndex - inStart + 1,inorderIndex + 1,atEnd,inorder);
        return root;
    }

}

C ++

// 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,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,pre_start + 1,in_start,pre_index - 1);
            root->right = build(preorder,pre_start + 1 + pre_index - in_start,pre_index + 1,in_end);
            return root;
        }
};

相关问答

错误1:Request method ‘DELETE‘ not supported 错误还原:...
错误1:启动docker镜像时报错:Error response from daemon:...
错误1:private field ‘xxx‘ is never assigned 按Alt...
报错如下,通过源不能下载,最后警告pip需升级版本 Requirem...