-
Notifications
You must be signed in to change notification settings - Fork 0
103. Binary Tree Zigzag Level Order Traversal #27
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?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,145 @@ | ||
| - [103. Binary Tree Zigzag Level Order Traversal](https://leetcode.com/problems/binary-tree-zigzag-level-order-traversal/description/) | ||
| - 条件 | ||
| - The number of nodes in the tree is in the range [0, 2000]. | ||
| - -100 <= Node.val <= 100 | ||
| - 方針 | ||
| - Queue | ||
| - [前回といた問題(102. Binary Tree Level Order Traversal)](https://github.com/hiroki-horiguchi-dev/leetcode/pull/26)と同様にQueueを用いる | ||
| - root を Queue に詰めながら、for でまわす方針は前回と同じだが、 | ||
| - zigzag にしないといけないので、2つの方針がある | ||
| 1. leftToRight を用意し、for のなかで Queue から取り出した TreeNode を `List<Integer>[→ → →] , List<Integer>[← ← ←]`に詰めるを繰り返す方針 | ||
| 2. for のなかで取り出した TreeNode を一旦 `List<Integer>[→ → →]` に詰めるけど、rightToLeft だけ、Collections.reverse() で反転させる | ||
| - コストの点で考えると、前者の方が逆順にするための計算量を食わないので良いと考える | ||
| - 時間計算量: ver1. `O(N)`, ver2. ~~`O(N^2)` Collections.reverse() に O(N) かかるため、[Collections.reverse() Method in Java with Examples | ||
| ](https://www.geeksforgeeks.org/java/collections-reverse-method-in-java-with-examples/)~~ 内側で回る回数の総和がNであって、毎回N回回るわけじゃないので `O(N)`とカウントして良い | ||
| - 空間計算量: ver1. `O(N)`, ver2. `O(N)` | ||
| - 実装時間 | ||
| - ver1. 20分 | ||
| - ver2. 2分 | ||
|
|
||
| ## Queue ver.1 LinkedListを使う | ||
|
|
||
| ```java | ||
| import java.util.LinkedList; | ||
|
|
||
| /** | ||
| * Definition for a binary tree node. | ||
| * public class TreeNode { | ||
| * int val; | ||
| * TreeNode left; | ||
| * TreeNode right; | ||
| * TreeNode() {} | ||
| * TreeNode(int val) { this.val = val; } | ||
| * TreeNode(int val, TreeNode left, TreeNode right) { | ||
| * this.val = val; | ||
| * this.left = left; | ||
| * this.right = right; | ||
| * } | ||
| * } | ||
| */ | ||
| class Solution { | ||
| public List<List<Integer>> zigzagLevelOrder(TreeNode root) { | ||
| List<List<Integer>> result = new ArrayList<>(); | ||
|
|
||
| if (root == null) { | ||
| return result; | ||
| } | ||
|
|
||
| Deque<TreeNode> nodes = new ArrayDeque<>(); | ||
| boolean isLeftToRight = true; | ||
| nodes.addLast(root); | ||
|
|
||
| while (!nodes.isEmpty()) { | ||
| // 本当は List<Integer> で受けたいが、jdk21未満だと List に addLast, addFirst がないため、コンパイルエラーになる可能性があるので、LinkedList で受けている。 | ||
|
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. LinkedList は、 add 毎に新しいオブジェクトが作られ、遅いイメージがあります。実際には速度を計ってみないと何とも言えません。 Deque<Integer> temp = new ArrayDeque<>() を使う手もあります。
Owner
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. |
||
| // LinkedList は List を継承しているので、result に add する分には問題ない | ||
| LinkedList<Integer> temp = new LinkedList<>(); | ||
| int size = nodes.size(); | ||
|
|
||
| for (int i = 0; i < size; i++) { | ||
| TreeNode node = nodes.pollFirst(); | ||
| if (isLeftToRight) { | ||
| temp.addLast(node.val); | ||
| } else { | ||
| temp.addFirst(node.val); | ||
| } | ||
|
|
||
| if (node.left != null) { | ||
| nodes.addLast(node.left); | ||
| } | ||
|
|
||
| if (node.right != null) { | ||
| nodes.addLast(node.right); | ||
| } | ||
| } | ||
|
|
||
| isLeftToRight = !isLeftToRight; | ||
| result.add(temp); | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
| } | ||
|
|
||
| ``` | ||
|
|
||
| ## Queue ver.2 Collections.reverse() を使う | ||
| ```java | ||
| /** | ||
| * Definition for a binary tree node. | ||
| * public class TreeNode { | ||
| * int val; | ||
| * TreeNode left; | ||
| * TreeNode right; | ||
| * TreeNode() {} | ||
| * TreeNode(int val) { this.val = val; } | ||
| * TreeNode(int val, TreeNode left, TreeNode right) { | ||
| * this.val = val; | ||
| * this.left = left; | ||
| * this.right = right; | ||
| * } | ||
| * } | ||
| */ | ||
| class Solution { | ||
| public List<List<Integer>> zigzagLevelOrder(TreeNode root) { | ||
| List<List<Integer>> result = new ArrayList<>(); | ||
|
|
||
| if (root == null) { | ||
| return result; | ||
| } | ||
|
|
||
| Deque<TreeNode> nodes = new ArrayDeque<>(); | ||
| boolean isLeftToRight = true; | ||
| nodes.addLast(root); | ||
|
|
||
| while (!nodes.isEmpty()) { | ||
| List<Integer> temp = new ArrayList<>(); | ||
| int size = nodes.size(); | ||
|
|
||
| for (int i = 0; i < size; i++) { | ||
| TreeNode node = nodes.pollFirst(); | ||
| temp.add(node.val); | ||
|
|
||
| if (node.left != null) { | ||
| nodes.addLast(node.left); | ||
| } | ||
|
|
||
| if (node.right != null) { | ||
| nodes.addLast(node.right); | ||
| } | ||
| } | ||
|
|
||
| if (!isLeftToRight) { | ||
| Collections.reverse(temp); | ||
| } | ||
| isLeftToRight = !isLeftToRight; | ||
| result.add(temp); | ||
| } | ||
|
|
||
| return result; | ||
| } | ||
| } | ||
|
|
||
| ``` | ||
|
|
||
| ## 次の問題に取り組む前の課題 | ||
| - Iterable, List, Queue, Dequeue, LinkedList の継承関係を把握する | ||
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.
識別子が動詞の原形や命令形から始まっている場合、関数名のように感じる場合があります。自分なら leftToRight と名付けると思います。
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.
コメントありがとうございます。
あれ、本当ですか・・・
is~ を、「その状態かどうか?」を示すフラグ用の変数名として、今まで参画したプロダクトの本番コードでも多々使ってきてしまいました。