Skip to content

Create Convert Sorted Array to Binary Search Tree.md#27

Open
irohafternoon wants to merge 1 commit intomainfrom
108.-Convert-Sorted-Array-to-Binary-Search-Tree
Open

Create Convert Sorted Array to Binary Search Tree.md#27
irohafternoon wants to merge 1 commit intomainfrom
108.-Convert-Sorted-Array-to-Binary-Search-Tree

Conversation

@irohafternoon
Copy link
Copy Markdown
Owner

if (left == right) {
return node;
}
if (left +1 == right) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

+1 の間にスペースを空けることをお勧めいたします。

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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

人によっては std::pair や std::tuple を避ける場合があります。理由は、何番目に何の値が入っているか分かりにくく感じるためです。代わりに構造体を定義し、その中に値を格納します。
スコープが短い場合は問題ないと思います。また、今回は構造化束縛で front() の戻り値を受け、変数名が書かれているので問題ないと思います。
チームの平均的な書き方に合わせることをお勧めいたします。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。
私の感想としても、構造化束縛で変数名が分かるので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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

TreeNode** でなく TreeNode* でも実装できるでしょうか。

Copy link
Copy Markdown
Owner Author

@irohafternoon irohafternoon Apr 26, 2025

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

コメントありがとうございます。
こちらのように書きました

#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);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

右半開区間でも実装できるでしょうか。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。
右半開区間の場合、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は近づき、いつか必ず逆転するので無限ループはない
後付けでもこれくらいしか考えつかない
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

このあたりでいいかと思います。

teachers' eye
- 無駄な変数や引数がないか(引数にしなくても情報が取れるパターンもある) https://github.com/ichika0615/arai60/pull/17/files#r2019815076
- 「手の運動」 https://github.com/ichika0615/arai60/pull/17/files#r2019099632
- とりあえず整理のために紙に書いてみるとか、手計算してみる、実験してみるみたいなニュアンスと思った
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

手の運動は、そうですね。少々面倒だとしても手を動かせば解決できるなら、ひとまず手を動かしながら考えます。

たとえば、「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;
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

これ、メモリーリークしていませんか。

TreeNode** を使うならば、私は pop した後に new することを想定しました。

あと、(*ptr_to_node) が多いので、変数に置いてもよいかと思います。

Copy link
Copy Markdown
Owner Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ありがとうございます。
おっしゃる通り、先のコードでは、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;
    }
};

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants