Conversation
|
|
||
| const TreeNode* const Solution::kSentinel = new TreeNode(0); | ||
| ``` | ||
| - TreeNode* 型のポインタをkSentinelとして定数に置きたかったのだが、これでよかったのか自信がない |
There was a problem hiding this comment.
ありがとうございます。
このように、ポインタでなく値で定数にして、&でポインタを取ると理解しました。
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(); |
There was a problem hiding this comment.
C++ の場合は、ダブルポインターで merged_node->left へのリファレンスを取ることによって、次のループの中で判断して代入することができますね。
そうすると、上の方の条件分岐をマージできます。
There was a problem hiding this comment.
ありがとうございます。
ダブルポインタを使って条件分岐をスッキリさせるということがあまりピンときていないので、少し考えてみたいと思います
There was a problem hiding this comment.
There was a problem hiding this comment.
ありがとうございます。
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); |
There was a problem hiding this comment.
この場合は、階層情報がいらないので、上の方のループでの DFS と同じ方法のほうが素直でしょう。
There was a problem hiding this comment.
ありがとうございます。上のコメントに、反映させた形で書き直しをしております
| std::cout << std::endl; | ||
|
|
||
| int d = 1; | ||
| (*B[0])[1] = &d; |
There was a problem hiding this comment.
ポインタ(参照)が指す先の中身を->で指しているのですね。
c++でのTreeNode* node のnode->valと似たようなものでしょうか。
逆に、c++にはないのかと思いました
| - root1を上書きしていくような手法は、入力を破壊するのでユーザーが驚くと思い、避けたい | ||
| - 基本的には再帰(非再帰DFS)を用いるか、BFSを用いるかには分かれる 再帰上限は問題ない | ||
|
|
||
| - 現実のユースケースを想像するのは難しい。全然考えても出てこないのでGPTに聞いてみた |
There was a problem hiding this comment.
これ、たとえば、分散処理をして戻ってきたデータをマージするなど、このようなことをしたくなる状況はそこそこあるように思います。
There was a problem hiding this comment.
ありがとうございます。
分散処理について、名前を聞いたことがあるレベルだったので、イメージがありませんでした。
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); | ||
| ``` |
This Problem
Merge Two Binary Trees
Next Problem
Convert Sorted Array to Binary Search Tree