108. Convert Sorted Array to Binary Search Tree#23
108. Convert Sorted Array to Binary Search Tree#23seal-azarashi wants to merge 4 commits intomainfrom
Conversation
| } | ||
|
|
||
| TreeNode root = new TreeNode(DUMMY_VAL); | ||
| ArrayDeque<NodeWithRange> stack = new ArrayDeque<>(); |
There was a problem hiding this comment.
一応、Stackというデータ構造がJavaにはあるようですが、ArrayDequeを使うのが一般的なのでしょうか??
https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html
There was a problem hiding this comment.
どちらが一般的かと言うと多分 Stack の方が一般的だと思います。ただ ArrayDeque の方が早いんですよね。
This class is likely to be faster than Stack when used as a stack, and faster than LinkedList when used as a queue.
スレッドセーフでないといった特徴があるので万能ではないですが、今回は特に選ぶのにあたってデメリットがなかったので、単純に早い方を選びました。
There was a problem hiding this comment.
ほー そうなんですね ありがとうございます
Stackを使うことで操作を制限できるというメリットと、速度のトレードオフを説明できると良さそうと思いました
具体的にどのくらいのパフォーマンス差があるかちょろっと調べただけでは出てきませんでしたが... (^^ ; )
There was a problem hiding this comment.
操作を制限するというのは使えるメソッドが限られるということなのかなと受け取ったのですが、それがメリットと言えるのかちょっと疑問に思いました👀 Deque 自体は特にパブリックアクセスが出来るようになっておらず、クラス内では今ある以上の使い方がされる想定がないので…
There was a problem hiding this comment.
パフォーマンスについては、少なくとも Leetcode の実行結果から読み取れるほどの差は見られないですね😇
There was a problem hiding this comment.
StackはCollections Framework以前の古いクラスなので、ArrayDequeを使ったほうがいいでしょう。
There was a problem hiding this comment.
なるほど古さで判断するという観点はありませんでした。
There was a problem hiding this comment.
前に ArrayDeque に null を格納しようとしたら落ちた記憶があります。
There was a problem hiding this comment.
@goto-untrapped
すいません見過ごしていました。確かに ArrayDeque は null を許容しないのも特徴の一つですね。
https://docs.oracle.com/en/java/javase/22/docs/api/java.base/java/util/ArrayDeque.html
実務で使っていた経験上、 null を許容しないクラスないしコレクションの方が扱いやすいケースが多かったので、この点も ArrayDeque を積極的に選びたくなる理由の一つだなと思いました。
|
|
||
| ```java | ||
| // 時間計算量: O(n log n): 各要素に対する操作と log n の深さのツリーの各レベルで行われる配列コピー操作 | ||
| // 空間計算量: O(n log n): log n の深さのツリーの各レベルで元配列のほぼ全要素をコピー |
| } | ||
|
|
||
| private TreeNode sortedArrayToBSTRecursively(int[] nums, int left, int right) { | ||
| if (right < left) { |
There was a problem hiding this comment.
たしかにそうですね。今までのレビューの傾向から (恐らく数直線上に比較する値を並べるイメージから) 小なりないし小なりイコールを好む方が多いなと思いこのようにしていましたが、 left, right に関しては言葉の意味する通りに並んでいない違和感が勝りますね。
修正しました: c56ef05
|
|
||
| ```java | ||
| // 時間計算量: O(n log n): 各要素に対する操作と log n の深さのツリーの各レベルで行われる配列コピー操作 | ||
| // 空間計算量: O(n log n): log n の深さのツリーの各レベルで元配列のほぼ全要素をコピー |
| } | ||
|
|
||
| private TreeNode buildBSTRecursively(int[] nums, int left, int right) { | ||
| if (right <= left) { |
| int middle = left + (right - left) / 2; | ||
| node.val = nums[middle]; | ||
| if (left <= middle - 1) { | ||
| node.left = new TreeNode(DUMMY_VAL); |
There was a problem hiding this comment.
メンバー変数へのリファレンスが取れると、これをしなくていいんですが、言語仕様上しかたがないですね。
There was a problem hiding this comment.
@oda
返信大変遅くなりました。
すいませんこのコメントがあまり理解できていないのですが、この行で初めて null だった node.left に値 (へのリファレンス) が代入される認識でいます。これをしなくていいとはつまり、リファレンスの取得とそれが指すメモリ領域の確保が不要になる (または効率的になる?) ということなのかなと解釈したのですが、そういったことが効率的に出来る言語があるのでしょうか?
https://leetcode.com/problems/convert-sorted-array-to-binary-search-tree/description/