-
Notifications
You must be signed in to change notification settings - Fork 0
105. Construct Binary Tree from Preorder and Inorder Traversal #43
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
return buildTreeWithIndex(0, 0, preorder.size(), preorder, inorder); | ||
} | ||
|
||
TreeNode* buildTreeWithIndex(int preorder_root_index, int inorder_left, int inorder_right, vector<int>& preorder, vector<int>& inorder) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
これはpublicでなくてもいいかなと思いました。
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
preorderとinorderにどちらもconstをつけると、関数内では変更しないことをこの行で伝えられると思いました。
} | ||
} | ||
root->left = buildTreeWithIndex(preorder_root_index + 1, inorder_left, root_index, preorder, inorder); | ||
root->right = buildTreeWithIndex(preorder_root_index + 1 + (root_index - inorder_left), root_index + 1, inorder_right, preorder, inorder); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
一つ目の引数ですが、ChatGptを使って理解できた(?)レベルでした。
コメントがあってもいいかもです🙇
// get left right tree node count | ||
int left_nodes_count = inorder_root_index; | ||
// split vectors and recursive to left right | ||
vector<int> preorder_left(preorder.begin() + 1, preorder.begin() + 1 + left_nodes_count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
inorderのルートを起点に左右に分割しvectorに要素を詰め込んでいると思うのですが
毎回全要素をコピーするよりは左右の範囲を管理するインデックスを使った方がコピーコストが下がるのかなと思いました。
int left_nodes_count = inorder_root_index; | ||
// split vectors and recursive to left right | ||
vector<int> preorder_left(preorder.begin() + 1, preorder.begin() + 1 + left_nodes_count); | ||
vector<int> inorder_left(inorder.begin(), inorder.begin() + left_nodes_count); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
C++20 からで私はあまり知らないですが、subrange 使う手はありますね。
TreeNode* buildTree(std::vector<int>& preorder, std::vector<int>& inorder) {
return buildTreeHelper(
std::ranges::subrange(preorder.begin(), preorder.end()),
std::ranges::subrange(inorder.begin(), inorder.end())
);
}
TreeNode* buildTreeHelper(std::ranges::subrange preorder, std::ranges::subrange inorder) {
vector<int> right_preorder(preorder.begin() + 1 + inorder_root_index, preorder.end()); | ||
vector<int> right_inorder(inorder.begin() + 1 + inorder_root_index, inorder.end()); | ||
root->right = buildTree(right_preorder, right_inorder); | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
preorder.begin() + 1 + inorder_root_index や inorder.begin() + inorder_root_index を変数としておくと区間をある境で分けていることが明確になる気もしました。+1 は末尾に書きたいと思いましたが趣味の範囲かもしれません。
class Solution { | ||
public: | ||
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { | ||
if (preorder.size() == 0) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
if (preorder.empty()) {
のほうがシンプルだと思います。
return root; | ||
} | ||
// get index of root in inorder | ||
int inorder_root_index; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
int inorder_root_index = std::distance(inorder.begin(), std::find(inorder.begin(), inorder.end(), preorder[0]));
のほうがシンプルだと思います。
stack<tuple<TreeNode*, int, int>> nodes_and_limits; | ||
// 番兵の設置、left/rightのlimitはinorderにおける左右部分木の存在可能な限界を示す、番兵の初期値としてmaxを与える | ||
nodes_and_limits.push({&dummy, numeric_limits<int>::max(), numeric_limits<int>::max()}); | ||
for (int p: preorder) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
p のあとにスペースを空けることをお勧めします。
class Solution { | ||
public: | ||
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { | ||
map<int, int> value_to_inorder_position; |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
個人的には value_to_inorder_index のほうが分かりやすいように思いました。
} | ||
stack<TreeNode*> nodes; | ||
// | ||
auto gather_descendants = [&](int node_position) { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
node_position が preorder の index か inorder の index か分かりづらく感じました。 preorder_index はいかがでしょうか?
class Solution { | ||
public: | ||
TreeNode* buildTree(vector<int>& preorder, vector<int>& inorder) { | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
buildTreeWithIndex() を呼び出しているだけのため、空行は消してしまってよいと思います。
hayashi-ay/leetcode#43
shining-ai/leetcode#29
Mike0121/LeetCode#12
sakupan102/arai60-practice#30
YukiMichishita/LeetCode#12
fhiyo/leetcode#31
kazukiii/leetcode#30
Ryotaro25/leetcode_first60#31
Yoshiki-Iwasa/Arai60#33
TORUS0818/leetcode#31
Ryotaro25/leetcode_first60#31
goto-untrapped/Arai60#53
https://github.com/SuperHotDogCat/coding-interview/pull/43/files