diff --git a/tree-bst/103.md b/tree-bst/103.md index e69de29..0860b86 100644 --- a/tree-bst/103.md +++ b/tree-bst/103.md @@ -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[→ → →] , List[← ← ←]`に詰めるを繰り返す方針 + 2. for のなかで取り出した TreeNode を一旦 `List[→ → →]` に詰めるけど、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> zigzagLevelOrder(TreeNode root) { + List> result = new ArrayList<>(); + + if (root == null) { + return result; + } + + Deque nodes = new ArrayDeque<>(); + boolean isLeftToRight = true; + nodes.addLast(root); + + while (!nodes.isEmpty()) { + // 本当は List で受けたいが、jdk21未満だと List に addLast, addFirst がないため、コンパイルエラーになる可能性があるので、LinkedList で受けている。 + // LinkedList は List を継承しているので、result に add する分には問題ない + LinkedList 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> zigzagLevelOrder(TreeNode root) { + List> result = new ArrayList<>(); + + if (root == null) { + return result; + } + + Deque nodes = new ArrayDeque<>(); + boolean isLeftToRight = true; + nodes.addLast(root); + + while (!nodes.isEmpty()) { + List 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 の継承関係を把握する \ No newline at end of file