-
Notifications
You must be signed in to change notification settings - Fork 0
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
108. Convert Sorted Array to Binary Search Tree #38
base: main
Are you sure you want to change the base?
Conversation
@@ -0,0 +1,21 @@ | |||
/* | |||
Time : O(N log N) | |||
Space : O(N) |
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.
Time: O(N)
Space: O(N^2)
ではないでしょうか?
sortedArrayToBST関数はnullptrを返す場合も含めると最悪で2N回(木が一直線の場合)呼ばれると思います。
空間計算量については、numsの部分コピーが、N + (N/2 + N/2) + (N/4 + N/4 + N/4 + N/4) + ... と作成されるのでO(N^2)だと思います
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.
空間計算量は時間計算量を超えることはないですね。
空間計算量ですが、この場合、必ず真ん中で分けているので、深さは log N で済みます。
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.
空間計算量については、numsの部分コピーが、N + N/2 + N/4 + ... と作成されるのでO(N)だと思います。
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.
@oda @nodchip
ご指摘ありがとうございます。まだ少し混乱しているので整理させてください
時間計算量: O(N logN)
auto left_nodes = vector<int>(nums.begin(), nums.begin() + center_index);
でnumsの半分の長さのコピーを作成するのにO(N/2)時間かかる(ここを失念していました)。再帰の深さは平衡木であるため(ここも失念していました)、logNで済む。よって、(N/2 + N/2) + (N/4 + N/4 + N/4 + N/4) + ... = N * logNとなり、O(N logN)時間でできる
空間計算量: O(N)
numsの部分コピーが、N + N/2 + N/4 + ... と作成される
こちらも(N/2 + N/2) + (N/4 + N/4 + N/4 + N/4) + ... = N * logN では?と思ったが、よく考えたらこれはスタックメモリの話をしていて、スタックメモリは関数呼び出しが終了すると解放されるので、ある瞬間に積み上がる最大のスタックフレームの個数はlogN個で、その中身は大きさが N + N/2 + N/4 + ... なのでO(N)
parents_and_ranges.emplace(&node, 0, nums.size()); | ||
while (!parents_and_ranges.empty()){ | ||
auto [parent_node_pointer, left, right] = parents_and_ranges.top(); | ||
parents_and_ranges.pop(); |
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.
この2行を1行でできないかなと思ったのですが、C++のstack.pop()は何も返さないんですね
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.
stack.pop() が値を返した場合、参照返しにできず、値返しにせざるを得ないものの、パフォーマンス的に微妙だからできないようにしたのかなと想像しました。実際に理由は分かりません。委員会の文書に載っているのでしょうか…。
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.
この記事におっしゃる通りのことが書いてありました
https://cpptruths.blogspot.com/2005/10/why-does-stdstackpop-returns-void.html
TreeNode* parent_node = new TreeNode(nums[mid]); | ||
*parent_node_pointer = parent_node; | ||
parents_and_ranges.emplace(&parent_node->left, left, mid); | ||
parents_and_ranges.emplace(&parent_node->right, mid + 1, right); |
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.
pushでもいいのかなと思ったのですが、emplaceとpushの違いがわからなくて調べました。pushだと引数をstackのtopに追加するという意味で、emplaceだとstackのtopでオブジェクトを構築して置くという意味で合ってますか?
それでここでemplaceを使っている理由は.push(new TreeNode(&parent_node->left, left, mid))
と書くより簡潔に書けるからということですか?
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.
emplaceを用いている理由はtupleのコピーを発生させないためではないでしょうか。
Pushes a new element on top of the stack. The element is constructed in-place, i.e. no copy or move operations are performed.
https://en.cppreference.com/w/cpp/container/stack/emplace
pushを用いた場合は、stackに入れる前に&parent_node->left, left, midや&parent_node->right, mid + 1, right)のコピーが作られると思います。
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.
それでここでemplaceを使っている理由は.push(new TreeNode(&parent_node->left, left, mid))と書くより簡潔に書けるからということですか?
nit: new いりません。
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 (nums.empty()) { | ||
return nullptr; | ||
} | ||
int center_index = nums.size() / 2; |
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.
変数名はmiddleが一般的かと思いました🙇♂️
参考にcecnterとmiddleの違いをAIに聞いてみました。
「center」は「ぴったり中央」を意味するのに対し、「middle」は「だいたい真ん中らへん」を意味します。
class Solution { | ||
public: | ||
TreeNode* sortedArrayToBST(vector<int>& nums) { | ||
stack<tuple<TreeNode**, int, int>> parents_and_ranges; |
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.
tuppleの代わりにstructを使うのも一つの方法だと思います。
googleのコーディング規約には下記のように記載ございます。
Prefer to use a struct instead of a pair or a tuple whenever the elements can have meaningful names.
参照
https://google.github.io/styleguide/cppguide.html#Structs_vs._Tuples
} | ||
int center_index = nums.size() / 2; | ||
auto node = new TreeNode(nums[center_index]); | ||
auto left_nodes = vector<int>(nums.begin(), nums.begin() + center_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.
vectorをコピー生成を行っているので、indexで管理するのもありかと思いました。
再帰を使わずに実装。 | ||
https://github.com/colorbox/leetcode/pull/37 | ||
を説いたときにある程度理解したつもりだったが、ポインタのポインタを使おうとするとだいぶ混乱する。 |
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.
最後のポインターは「を保存する先」という意味になりますね。
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.
特に問題ないかと思います。
@@ -0,0 +1,21 @@ | |||
/* | |||
Time : O(N log N) | |||
Space : O(N) |
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.
空間計算量については、numsの部分コピーが、N + N/2 + N/4 + ... と作成されるのでO(N)だと思います。
} | ||
|
||
private: | ||
TreeNode* sorted_array_to_bst_recursive(vector<int>& nums, int left, int right) { |
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.
nums は内部で変更されないため、 const を付けたほうがよいと思います。個人的には、変更しない変数について、プリミティブ型は const をつけず、複合型は const を付けています。ただ、あくまで個人的な目安のため、所属するチームの平均的な書き方に合わせることをお勧めいたします。
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.
コメントありがとうございます、このnumsに対しては変更を加えないのでconstをつけるほうがよいですね。
parents_and_ranges.emplace(&node, 0, nums.size()); | ||
while (!parents_and_ranges.empty()){ | ||
auto [parent_node_pointer, left, right] = parents_and_ranges.top(); | ||
parents_and_ranges.pop(); |
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.
stack.pop() が値を返した場合、参照返しにできず、値返しにせざるを得ないものの、パフォーマンス的に微妙だからできないようにしたのかなと想像しました。実際に理由は分かりません。委員会の文書に載っているのでしょうか…。
108. Convert Sorted Array to Binary Search Tree
https://discord.com/channels/1084280443945353267/1183683738635346001/1209195844511858688
hayashi-ay/leetcode#29
shining-ai/leetcode#24
rossy0213/leetcode#13
sakupan102/arai60-practice#25
Mike0121/LeetCode#13
fhiyo/leetcode#26
Yoshiki-Iwasa/Arai60#28
kazukiii/leetcode#25
TORUS0818/leetcode#26
Ryotaro25/leetcode_first60#26
goto-untrapped/Arai60#48
seal-azarashi/leetcode#23
https://github.com/SuperHotDogCat/coding-interview/pull/40/files
hroc135/leetcode#23
rihib/leetcode#54
olsen-blue/Arai60#24