Skip to content

108. Convert Sorted Array to Binary Search Tree#23

Open
seal-azarashi wants to merge 4 commits intomainfrom
convert-sorted-array-to-binary-search-tree
Open

108. Convert Sorted Array to Binary Search Tree#23
seal-azarashi wants to merge 4 commits intomainfrom
convert-sorted-array-to-binary-search-tree

Conversation

@seal-azarashi
Copy link
Copy Markdown
Owner

}

TreeNode root = new TreeNode(DUMMY_VAL);
ArrayDeque<NodeWithRange> stack = new ArrayDeque<>();
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

一応、Stackというデータ構造がJavaにはあるようですが、ArrayDequeを使うのが一般的なのでしょうか??
https://docs.oracle.com/javase/8/docs/api/java/util/Stack.html

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.

どちらが一般的かと言うと多分 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.

from: https://docs.oracle.com/en%2Fjava%2Fjavase%2F22%2Fdocs%2Fapi%2F%2F/java.base/java/util/ArrayDeque.html

スレッドセーフでないといった特徴があるので万能ではないですが、今回は特に選ぶのにあたってデメリットがなかったので、単純に早い方を選びました。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

ほー そうなんですね ありがとうございます

Stackを使うことで操作を制限できるというメリットと、速度のトレードオフを説明できると良さそうと思いました

具体的にどのくらいのパフォーマンス差があるかちょろっと調べただけでは出てきませんでしたが... (^^ ; )

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.

操作を制限するというのは使えるメソッドが限られるということなのかなと受け取ったのですが、それがメリットと言えるのかちょっと疑問に思いました👀 Deque 自体は特にパブリックアクセスが出来るようになっておらず、クラス内では今ある以上の使い方がされる想定がないので…

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.

パフォーマンスについては、少なくとも Leetcode の実行結果から読み取れるほどの差は見られないですね😇

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

StackはCollections Framework以前の古いクラスなので、ArrayDequeを使ったほうがいいでしょう。

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.

前に ArrayDeque に null を格納しようとしたら落ちた記憶があります。

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.

@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 の深さのツリーの各レベルで元配列のほぼ全要素をコピー
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

空間計算量はO(n)ではないでしょうか?

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nが何の数字なのか、仮に明らかな場合にも記載すると良いと思います。

}

private TreeNode sortedArrayToBSTRecursively(int[] nums, int left, int right) {
if (right < left) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

個人的にleft > rightの方が好みです。

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.

たしかにそうですね。今までのレビューの傾向から (恐らく数直線上に比較する値を並べるイメージから) 小なりないし小なりイコールを好む方が多いなと思いこのようにしていましたが、 left, right に関しては言葉の意味する通りに並んでいない違和感が勝りますね。
修正しました: c56ef05


```java
// 時間計算量: O(n log n): 各要素に対する操作と log n の深さのツリーの各レベルで行われる配列コピー操作
// 空間計算量: O(n log n): log n の深さのツリーの各レベルで元配列のほぼ全要素をコピー
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

nが何の数字なのか、仮に明らかな場合にも記載すると良いと思います。

}

private TreeNode buildBSTRecursively(int[] nums, int left, int right) {
if (right <= left) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

left >= rightの方が好みです。

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.

こちらで合わせて修正しました: #23 (comment)

int middle = left + (right - left) / 2;
node.val = nums[middle];
if (left <= middle - 1) {
node.left = new TreeNode(DUMMY_VAL);
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.

@oda
返信大変遅くなりました。
すいませんこのコメントがあまり理解できていないのですが、この行で初めて null だった node.left に値 (へのリファレンス) が代入される認識でいます。これをしなくていいとはつまり、リファレンスの取得とそれが指すメモリ領域の確保が不要になる (または効率的になる?) ということなのかなと解釈したのですが、そういったことが効率的に出来る言語があるのでしょうか?

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.

7 participants