Create Convert Sorted Array to Binary Search Tree.md#27
Create Convert Sorted Array to Binary Search Tree.md#27irohafternoon wants to merge 1 commit intomainfrom
Conversation
| if (left == right) { | ||
| return node; | ||
| } | ||
| if (left +1 == right) { |
| public: | ||
| TreeNode* sortedArrayToBST(const std::vector<int>& nums) { | ||
| //tuple = (left_index, right_index, ptr_to_node) | ||
| std::queue<std::tuple<int, int, TreeNode**>> nodes_for_BST; |
There was a problem hiding this comment.
人によっては std::pair や std::tuple を避ける場合があります。理由は、何番目に何の値が入っているか分かりにくく感じるためです。代わりに構造体を定義し、その中に値を格納します。
スコープが短い場合は問題ないと思います。また、今回は構造化束縛で front() の戻り値を受け、変数名が書かれているので問題ないと思います。
チームの平均的な書き方に合わせることをお勧めいたします。
There was a problem hiding this comment.
ありがとうございます。
私の感想としても、構造化束縛で変数名が分かるのでtupleを使って良いかなと考えていました。
実務ではチームの方針を確認するようにいたします。
| public: | ||
| TreeNode* sortedArrayToBST(const std::vector<int>& nums) { | ||
| //tuple = (left_index, right_index, ptr_to_node) | ||
| std::queue<std::tuple<int, int, TreeNode**>> nodes_for_BST; |
There was a problem hiding this comment.
TreeNode** でなく TreeNode* でも実装できるでしょうか。
There was a problem hiding this comment.
コメントありがとうございます。
こちらのように書きました
#include <vector>
#include <queue>
class Solution {
public:
TreeNode* sortedArrayToBST(const std::vector<int>& nums) {
if (nums.empty()) {
return nullptr;
}
std::queue<std::tuple<int, int, TreeNode*>> nodes_for_BST;
TreeNode* root = new TreeNode();
nodes_for_BST.emplace(0, nums.size() - 1, root);
while (!(nodes_for_BST).empty()) {
auto [left_index, right_index, node] = nodes_for_BST.front();
nodes_for_BST.pop();
int mid_index = (left_index + right_index) / 2;
node->val = nums[mid_index];
if (left_index <= mid_index - 1) {
node->left = new TreeNode();
nodes_for_BST.emplace(left_index, mid_index - 1, node->left);
}
if (mid_index + 1 <= right_index) {
node->right = new TreeNode();
nodes_for_BST.emplace(mid_index + 1, right_index, node->right);
}
}
return root;
}
};| class Solution { | ||
| public: | ||
| TreeNode* sortedArrayToBST(const std::vector<int>& nums) { | ||
| return SortedArrayToBSTHelper(nums, 0, nums.size() - 1); |
There was a problem hiding this comment.
ありがとうございます。
右半開区間の場合、indexの満たすべき条件は left_index < right_indexになります。また、right_indexの初期値がnums.size()となります。
以下のように書きました
class Solution {
public:
TreeNode* sortedArrayToBST(const std::vector<int>& nums) {
return ContructBST(nums, 0, nums.size());
}
private:
TreeNode* ContructBST(const std::vector<int>& nums, int left_index, int right_index) {
if(!(left_index < right_index)) {
return nullptr;
}
int mid_index = (left_index + right_index) / 2;
TreeNode* node = new TreeNode(nums[mid_index]);
node->left = ContructBST(nums, left_index, mid_index);
node->right = ContructBST(nums, mid_index + 1, right_index);
return node;
}
};| - left == rightから更に進むと、必ずleftとrightが逆転するのでnullptrを返すのは合っている | ||
| - left = right = 0や右端の時も問題ない | ||
| - 木が深くなればleft-rightは近づき、いつか必ず逆転するので無限ループはない | ||
| 後付けでもこれくらいしか考えつかない |
| teachers' eye | ||
| - 無駄な変数や引数がないか(引数にしなくても情報が取れるパターンもある) https://github.com/ichika0615/arai60/pull/17/files#r2019815076 | ||
| - 「手の運動」 https://github.com/ichika0615/arai60/pull/17/files#r2019099632 | ||
| - とりあえず整理のために紙に書いてみるとか、手計算してみる、実験してみるみたいなニュアンスと思った |
There was a problem hiding this comment.
手の運動は、そうですね。少々面倒だとしても手を動かせば解決できるなら、ひとまず手を動かしながら考えます。
たとえば、「O(n!) なアルゴリズムがあります。n がいくらくらいまで計算できそうですか?」というときに、「いいから1から10まで掛け算しよう。小さすぎたら20までかけよう。」みたいな話です。
| auto [left_index, right_index, ptr_to_node] = nodes_for_BST.front(); | ||
| nodes_for_BST.pop(); | ||
| if (!(left_index <= right_index)) { | ||
| *ptr_to_node = nullptr; |
There was a problem hiding this comment.
これ、メモリーリークしていませんか。
TreeNode** を使うならば、私は pop した後に new することを想定しました。
あと、(*ptr_to_node) が多いので、変数に置いてもよいかと思います。
There was a problem hiding this comment.
ありがとうございます。
おっしゃる通り、先のコードでは、newで確保したメモリのノードが条件を満たさないときにnullptrに書き換えており、newで確保したメモリの番地の情報がわからなくなりdeleteできなくなり、メモリリークすると理解しました。
順番が逆で、一旦nullptrにした後、有効なノードであれば、ダブルポインタを使って、newで新たに確保したメモリの番地に書き換えるべきでした。
(*ptr_to_node)をnodeという変数において、以下のように書きました
#include <queue>
#include <vector>
class Solution {
public:
TreeNode* sortedArrayToBST(const std::vector<int>& nums) {
//tuple = (left_index, right_index, ptr_to_node)
std::queue<std::tuple<int, int, TreeNode**>> nodes_for_BST;
TreeNode* root = new TreeNode();
nodes_for_BST.emplace(0, nums.size() - 1, &root);
while (!nodes_for_BST.empty()) {
auto [left_index, right_index, ptr_to_node] = nodes_for_BST.front();
nodes_for_BST.pop();
if (!(left_index <= right_index)) {
continue;
}
int mid_index = (left_index + right_index) / 2;
*ptr_to_node = new TreeNode(nums[mid_index]);
TreeNode* node = *ptr_to_node;
nodes_for_BST.emplace(left_index, mid_index - 1, &(node->left));
nodes_for_BST.emplace(mid_index + 1, right_index, &(node->right));
}
return root;
}
};
This Problem
Convert Sorted Array to Binary Search Tree
Next Problem
Path Sum