From 6df017863f41c02430b656fa3333d3cbbfe48d18 Mon Sep 17 00:00:00 2001 From: colorbox Date: Sun, 2 Feb 2025 15:08:34 +0900 Subject: [PATCH] 108. Convert Sorted Array to Binary Search Tree --- 108/step1.cpp | 30 ++++++++++++++++++++++++++++++ 108/step2_1.cpp | 21 +++++++++++++++++++++ 108/step2_2.cpp | 23 +++++++++++++++++++++++ 108/step2_3.cpp | 30 ++++++++++++++++++++++++++++++ 108/step3.cpp | 24 ++++++++++++++++++++++++ 5 files changed, 128 insertions(+) create mode 100644 108/step1.cpp create mode 100644 108/step2_1.cpp create mode 100644 108/step2_2.cpp create mode 100644 108/step2_3.cpp create mode 100644 108/step3.cpp diff --git a/108/step1.cpp b/108/step1.cpp new file mode 100644 index 0000000..b6ad429 --- /dev/null +++ b/108/step1.cpp @@ -0,0 +1,30 @@ +/* +Solve Time : 23:54 + +Time : O(N log N) +Space : (N) + +方針はほぼ最初にできていたが、右側の再帰部分でミスってハマった。 +右半分をreverseして再帰しないといけないという勘違いをしていた。 +*/ +class Solution { +public: + TreeNode* sortedArrayToBST(vector& nums) { + if (nums.size() == 0) { + return nullptr; + } + if (nums.size() == 1) { + return new TreeNode(nums[0]); + } + int half_size = nums.size() / 2; + vector left_nums; + for (int i = 0; i < half_size; ++i) { + left_nums.push_back(nums[i]); + } + vector right_nums; + for (int i = half_size + 1; i < nums.size(); ++i) { + right_nums.push_back(nums[i]); + } + return new TreeNode(nums[half_size], sortedArrayToBST(left_nums), sortedArrayToBST(right_nums)); + } +}; diff --git a/108/step2_1.cpp b/108/step2_1.cpp new file mode 100644 index 0000000..d6503ae --- /dev/null +++ b/108/step2_1.cpp @@ -0,0 +1,21 @@ +/* +Time : O(N log N) +Space : O(N) + +nums.size==1の無駄な処理減らし、vectorのコピーをループを使わずに実行するようにした。 +*/ +class Solution { +public: + TreeNode* sortedArrayToBST(vector& nums) { + if (nums.empty()) { + return nullptr; + } + int center_index = nums.size() / 2; + auto node = new TreeNode(nums[center_index]); + auto left_nodes = vector(nums.begin(), nums.begin() + center_index); + node->left = sortedArrayToBST(left_nodes); + auto right_nodes = vector(nums.begin() + center_index + 1, nums.end()); + node->right = sortedArrayToBST(right_nodes); + return node; + } +}; diff --git a/108/step2_2.cpp b/108/step2_2.cpp new file mode 100644 index 0000000..7a41598 --- /dev/null +++ b/108/step2_2.cpp @@ -0,0 +1,23 @@ +/* +Time : O(N) +Space : O(N) +インデックスを使用してvectorのコピーをなくした。 +*/ +class Solution { + public: + TreeNode* sortedArrayToBST(vector& nums) { + return sorted_array_to_bst_recursive(nums, 0, nums.size()); + } + + private: + TreeNode* sorted_array_to_bst_recursive(vector& nums, int left, int right) { + if (left >= right) { + return nullptr; + } + int mid = (left + right) / 2; + auto node = new TreeNode(nums[mid]); + node->left = sorted_array_to_bst_recursive(nums, left, mid); + node->right = sorted_array_to_bst_recursive(nums, mid + 1, right); + return node; + } +}; diff --git a/108/step2_3.cpp b/108/step2_3.cpp new file mode 100644 index 0000000..7a324e6 --- /dev/null +++ b/108/step2_3.cpp @@ -0,0 +1,30 @@ +/* +Time : O(N) +Space : O(N) + +再帰を使わずに実装。 +https://github.com/colorbox/leetcode/pull/37 +を説いたときにある程度理解したつもりだったが、ポインタのポインタを使おうとするとだいぶ混乱する。 + +*/ +class Solution { + public: + TreeNode* sortedArrayToBST(vector& nums) { + stack> parents_and_ranges; + TreeNode *node; + parents_and_ranges.emplace(&node, 0, nums.size()); + while (!parents_and_ranges.empty()){ + auto [parent_node_pointer, left, right] = parents_and_ranges.top(); + parents_and_ranges.pop(); + if (left >= right) { + continue; + } + int mid = (left + right) / 2; + TreeNode* parent_node = new TreeNode(nums[mid]); + *parent_node_pointer = parent_node; + parents_and_ranges.emplace(&parent_node->left, left, mid); + parents_and_ranges.emplace(&parent_node->right, mid + 1, right); + } + return node; + } +}; diff --git a/108/step3.cpp b/108/step3.cpp new file mode 100644 index 0000000..b72e296 --- /dev/null +++ b/108/step3.cpp @@ -0,0 +1,24 @@ +/* +再帰は慣れているので、ポインタに慣れるためにポインタを使用した解法でstep3 +*/ +class Solution { + public: + TreeNode* sortedArrayToBST(vector& nums) { + stack> node_pointers_and_ranges; + TreeNode* root; + node_pointers_and_ranges.emplace(&root, 0, nums.size()); + while (!node_pointers_and_ranges.empty()) { + auto [node_pointer, left, right] = node_pointers_and_ranges.top(); + node_pointers_and_ranges.pop(); + if (left >= right) { + continue; + } + int mid = (left + right) / 2; + TreeNode* node = new TreeNode(nums[mid]); + *node_pointer = node; + node_pointers_and_ranges.emplace(&node->left, left, mid); + node_pointers_and_ranges.emplace(&node->right, mid + 1, right); + } + return root; + } +};