Skip to content

617. merge two binary trees#26

Open
irohafternoon wants to merge 4 commits intomainfrom
617.-Merge-Two-Binary-Trees
Open

617. merge two binary trees#26
irohafternoon wants to merge 4 commits intomainfrom
617.-Merge-Two-Binary-Trees

Conversation

@irohafternoon
Copy link
Copy Markdown
Owner


const TreeNode* const Solution::kSentinel = new TreeNode(0);
```
- TreeNode* 型のポインタをkSentinelとして定数に置きたかったのだが、これでよかったのか自信がない
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

@irohafternoon irohafternoon Apr 24, 2025

Choose a reason for hiding this comment

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

ありがとうございます。
このように、ポインタでなく値で定数にして、&でポインタを取ると理解しました。

class Solution {
public:
    TreeNode* mergeTrees(const TreeNode* root1, const TreeNode* root2) {
        if (!root1 && !root2) {
            return nullptr;
        }
        if (!root1) {
            root1 = &kSentinel;
        }
        if (!root2) {
            root2 = &kSentinel;
        } 
        return new TreeNode(root1->val + root2->val,
                            mergeTrees(root1->left, root2->left),
                            mergeTrees(root1->right, root2->right));
    }
private:           
    static const TreeNode const kSentinel;
};
const TreeNode const Solution::kSentinel = TreeNode(0); 

}
merged_node->val = node1->val + node2->val;
if (node1->left || node2->left) {
merged_node->left = new TreeNode();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

C++ の場合は、ダブルポインターで merged_node->left へのリファレンスを取ることによって、次のループの中で判断して代入することができますね。

そうすると、上の方の条件分岐をマージできます。

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.

ありがとうございます。
ダブルポインタを使って条件分岐をスッキリさせるということがあまりピンときていないので、少し考えてみたいと思います

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.

ありがとうございます。
discordを読んで理解できました。
キューに追加する前に両方がnullでないか判断する代わりに、とりあえずqueueに入れて、無効(null)なノードはキューからpopした時にそのノードをnullptrにしたい。
後からTreeNode* 自体を編集したいので、TreeNode* への参照(ダブルポインタ)が必要

#include <algorithm>
#include <vector>

class Solution {
public:
    TreeNode* mergeTrees(const TreeNode* root1, const TreeNode* root2) {
        // tuple {merge_base1, merge_base2, ptr_to_merged_node}
        std::queue<std::tuple<const TreeNode*, const TreeNode*, TreeNode**>> nodes_to_merge;
        TreeNode* new_head = new TreeNode();
        nodes_to_merge.emplace(root1, root2, &new_head);
        while (!nodes_to_merge.empty()) {
            auto [node1, node2, ptr_to_merged_node] = nodes_to_merge.front();
            nodes_to_merge.pop();
            if (!node1 && !node2) {
                *ptr_to_merged_node = nullptr;
                continue;
            }
            if (!node1) {
                node1 = kSentinel;
            }
            if (!node2) {
                node2 = kSentinel;
            }
            (*ptr_to_merged_node)->val = node1->val + node2->val;
            (*ptr_to_merged_node)->left = new TreeNode();
            nodes_to_merge.emplace(node1->left, node2->left, &((*ptr_to_merged_node)->left));
            (*ptr_to_merged_node)->right = new TreeNode();
            nodes_to_merge.emplace(node1->right, node2->right, &((*ptr_to_merged_node)->right));
        }
        return new_head;
    }
private:           
    static const TreeNode* const kSentinel;
};
const TreeNode* const Solution::kSentinel = new TreeNode(0); 

このようにすっきりしました

next_nodes.emplace_back(node1->right, node2->right, merged_node->right);
}
}
std::swap(current_nodes, next_nodes);
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

この場合は、階層情報がいらないので、上の方のループでの DFS と同じ方法のほうが素直でしょう。

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.

ありがとうございます。上のコメントに、反映させた形で書き直しをしております

std::cout << std::endl;

int d = 1;
(*B[0])[1] = &d;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Perl だと ->[0] という演算子があるんですが。

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.

ポインタ(参照)が指す先の中身を->で指しているのですね。
c++でのTreeNode* node のnode->valと似たようなものでしょうか。
逆に、c++にはないのかと思いました

- root1を上書きしていくような手法は、入力を破壊するのでユーザーが驚くと思い、避けたい
- 基本的には再帰(非再帰DFS)を用いるか、BFSを用いるかには分かれる 再帰上限は問題ない

- 現実のユースケースを想像するのは難しい。全然考えても出てこないのでGPTに聞いてみた
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.

ありがとうございます。
分散処理について、名前を聞いたことがあるレベルだったので、イメージがありませんでした。
https://ja.wikipedia.org/wiki/%E5%88%86%E6%95%A3%E3%82%B3%E3%83%B3%E3%83%94%E3%83%A5%E3%83%BC%E3%83%86%E3%82%A3%E3%83%B3%E3%82%B0
コンピュータ内、コンピュータ間で同一プログラムの処理を分割する手法なのですね
こちらの例だと、各ノードでの挙動を(別ノードから値が返ってきた時の操作など)まとめて記述するDFSの方が実態に沿っていそうだと思いました

static const TreeNode* const kSentinel;
};
const TreeNode* const Solution::kSentinel = new TreeNode(0);
```
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

特に問題ないと思いました

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