From 7e6cacc07d41f951b4bc0eedb7b1ea9c01947c23 Mon Sep 17 00:00:00 2001 From: Ace-Krypton Date: Tue, 19 Sep 2023 17:18:43 +0200 Subject: [PATCH] Added Construct Binary Tree from Preorder and Inorder Traversal --- CMakeLists.txt | 11 +++ Easy/InvertBinaryTree/include/solution.hpp | 2 +- Easy/SymmetricTree/include/solution.hpp | 2 +- .../include/solution.hpp | 80 +++++++++++++++++++ .../tests/test.cpp | 10 +++ 5 files changed, 103 insertions(+), 2 deletions(-) create mode 100644 Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/include/solution.hpp create mode 100644 Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/tests/test.cpp diff --git a/CMakeLists.txt b/CMakeLists.txt index 8e22963..a9e8398 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -788,4 +788,15 @@ add_executable(SymmetricTree target_link_libraries( SymmetricTree GTest::gtest_main +) + +add_executable(ConstructBinaryTreeFromPreorderAndInorderTraversal + Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/include/solution.hpp + Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/tests/test.cpp +) + +# Construct Binary Tree from Preorder and Inorder Traversal +target_link_libraries( + ConstructBinaryTreeFromPreorderAndInorderTraversal + GTest::gtest_main ) \ No newline at end of file diff --git a/Easy/InvertBinaryTree/include/solution.hpp b/Easy/InvertBinaryTree/include/solution.hpp index 1869c25..c9f3329 100644 --- a/Easy/InvertBinaryTree/include/solution.hpp +++ b/Easy/InvertBinaryTree/include/solution.hpp @@ -6,7 +6,7 @@ #include struct TreeNode { - int32_t value; + const int32_t value; TreeNode *left; TreeNode *right; explicit TreeNode(int32_t value) : diff --git a/Easy/SymmetricTree/include/solution.hpp b/Easy/SymmetricTree/include/solution.hpp index 2dd26d1..4a59534 100644 --- a/Easy/SymmetricTree/include/solution.hpp +++ b/Easy/SymmetricTree/include/solution.hpp @@ -6,7 +6,7 @@ #include struct TreeNode { - int32_t value; + const int32_t value; TreeNode *left; TreeNode *right; explicit TreeNode(int32_t value) : diff --git a/Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/include/solution.hpp b/Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/include/solution.hpp new file mode 100644 index 0000000..c98ef6d --- /dev/null +++ b/Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/include/solution.hpp @@ -0,0 +1,80 @@ +#pragma once + +#include +#include +#include +#include + +struct TreeNode { + const int32_t value; + TreeNode *left; + TreeNode *right; + explicit TreeNode(int32_t value) : + value(value), left(nullptr), right(nullptr) { } +}; + +class Solution { +public: + static auto build_tree(const std::vector &preorder, + const std::vector &inorder) -> TreeNode* { + auto pre = preorder.begin(); + auto in = inorder.begin(); + + std::function construct = [&](int32_t stop) -> TreeNode* { + if (pre == preorder.end() || *in == stop) return (TreeNode*)nullptr; + auto *node = new TreeNode{*(pre++)}; + node->left = construct(node->value); + assert (*in == node->value); + in++; + node->right = construct(stop); + return node; + }; + + return construct(std::numeric_limits::max()); + } + + [[maybe_unused]] static auto build_tree_tle(const std::vector &preorder, + const std::vector &inorder) -> TreeNode* { + std::unordered_map inorder_map; + for (int i = 0; i < inorder.size(); ++i) { + inorder_map[inorder[i]] = i; + } + + return helper(preorder, 0, preorder.size() - 1, + inorder_map, 0, inorder.size() - 1); + } + + static auto preorder(TreeNode *node) -> void { + std::function print = + [&] (TreeNode *node) -> void { + if (node == nullptr) return; + std::cout << node->value << ' '; + print(node->left); + print(node->right); + }; + + print(node); + } + +private: + static auto helper(const std::vector &preorder, const int32_t pre_start, + const std::size_t pre_end, std::unordered_map &inorder_map, + const int32_t in_start, const std::size_t in_end) -> TreeNode* { + if (pre_start > pre_end || in_start > in_end) return nullptr; + + const int32_t root_val = preorder[pre_start]; + auto *root = new TreeNode(root_val); + + const int32_t in_root_index = inorder_map[root_val]; + const int32_t left_subtree_size = in_root_index - in_start; + + root->left = helper(preorder, pre_start + 1, + pre_start + left_subtree_size, + inorder_map, in_start, in_root_index - 1); + root->right = helper(preorder, pre_start + left_subtree_size + 1, + pre_end, inorder_map, + in_root_index + 1, in_end); + + return root; + } +}; diff --git a/Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/tests/test.cpp b/Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/tests/test.cpp new file mode 100644 index 0000000..6a738e2 --- /dev/null +++ b/Medium/ConstructBinaryTreeFromPreorderAndInorderTraversal/tests/test.cpp @@ -0,0 +1,10 @@ +#include "../include/solution.hpp" + +auto main() -> int { + std::vector preorder = {3, 9, 20, 15, 7}; + std::vector inorder = {9, 3, 15, 20, 7}; + + Solution::preorder(Solution::build_tree(preorder, inorder)); + + return 0; +}