Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
29 changes: 29 additions & 0 deletions arai60/binary-tree-zigzag-level-order-traversal/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
## 考察
- 初見の問題
- 方針
- BFS
- レベルごとに探索して、levelを0始まりで考えたときに奇数なら逆順にして答えに追加すれば良さそう
- 各reverse処理の計算量は要素数オーダーかかるが、全体としてはノード数で抑えられるので、amortized O(1)
- time: O(n), space: O(n)
- DFS
- DFSでも出来るが、前回同様DFSで解くメリットは特にない
- DFSは前回書いたので今回はスキップ
- BFSで、vectorを2つ用意する形で実装する

## Step1
- 他の人のPRを検索
- https://github.com/fhiyo/leetcode/pull/29
- 文字通りzigzagにtraverseしている
- おそらくこれが想定解
- どうやって考えたら思い付けるか落とし込むことが出来なかったので、一旦覚える
- from_leftを用意している
- levelの偶奇で判定するより可読性が高そう
- https://github.com/YukiMichishita/LeetCode/pull/11
- reverseしなくてもdequeを使えば、逆順になる
- https://github.com/sakupan102/arai60-practice/pull/28
- `step2_zigzag_traverse.cpp` と `spte2_deque.cpp` を追加

## Step3
- 1回目: 3m52s
- 2回目: 3m20s
- 3回目: 3m25s
36 changes: 36 additions & 0 deletions arai60/binary-tree-zigzag-level-order-traversal/step1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
if (!root) return {};
vector<TreeNode*> nodes_to_visit;
nodes_to_visit.push_back(root);
vector<vector<int>> answer;
int level = 0;
while (!nodes_to_visit.empty()) {
vector<int> values_in_level;
vector<TreeNode*> nodes_in_next_level;
for (int i = 0; i < nodes_to_visit.size(); i++) {
TreeNode* node = nodes_to_visit[i];
values_in_level.push_back(node->val);
if (node->left) nodes_in_next_level.push_back(node->left);
if (node->right) nodes_in_next_level.push_back(node->right);
}
if (level % 2 == 1) reverse(values_in_level.begin(), values_in_level.end());
answer.push_back(move(values_in_level));
swap(nodes_to_visit, nodes_in_next_level);
level++;
}
return answer;
}
};
39 changes: 39 additions & 0 deletions arai60/binary-tree-zigzag-level-order-traversal/step2_deque.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
if (!root) return {};
vector<TreeNode*> nodes_to_visit;
nodes_to_visit.push_back(root);
vector<vector<int>> answer;
int level = 0;
while (!nodes_to_visit.empty()) {
deque<int> values_in_level;
vector<TreeNode*> nodes_in_next_level;
for (int i = 0; i < nodes_to_visit.size(); i++) {
TreeNode* node = nodes_to_visit[i];
if (level % 2 == 0) {
values_in_level.push_back(node->val);
} else {
values_in_level.push_front(node->val);
}
if (node->left) nodes_in_next_level.push_back(node->left);
if (node->right) nodes_in_next_level.push_back(node->right);
}
answer.emplace_back(values_in_level.begin(), values_in_level.end());
swap(nodes_to_visit, nodes_in_next_level);
level++;
}
return answer;
}
};
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
if (!root) return {};
vector<TreeNode*> nodes;
nodes.push_back(root);
bool left_to_right = true;
vector<vector<int>> answer;
while (!nodes.empty()) {
auto& values_in_level = answer.emplace_back();
vector<TreeNode*> nodes_in_next_level;
for (int i = nodes.size() - 1; i >= 0; i--) {
TreeNode* node = nodes[i];
values_in_level.push_back(node->val);
if (left_to_right) {
if (node->left) nodes_in_next_level.push_back(node->left);
if (node->right) nodes_in_next_level.push_back(node->right);
} else {
if (node->right) nodes_in_next_level.push_back(node->right);
if (node->left) nodes_in_next_level.push_back(node->left);
}
}
swap(nodes, nodes_in_next_level);
left_to_right = !left_to_right;
}
return answer;
}
};
39 changes: 39 additions & 0 deletions arai60/binary-tree-zigzag-level-order-traversal/step3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
/**
* Definition for a binary tree node.
* struct TreeNode {
* int val;
* TreeNode *left;
* TreeNode *right;
* TreeNode() : val(0), left(nullptr), right(nullptr) {}
* TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
* TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
* };
*/
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
if (!root) return {};
vector<TreeNode*> nodes;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

あえてvectorをstackっぽく使っているように見えた (LIFOの順に要素を見ているので) んですが、stackでなくvectorを使った理由ってありますか?

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.

いつもありがとうございます。
強いこだわりがある訳ではないですが、以前頂いたこちらのコメントを参考に、今回の場合も順不同で push, pop する訳ではないため vector を使っています。#27 (comment)

nodes.push_back(root);
bool left_to_right = true;
vector<vector<int>> answer;
while (!nodes.empty()) {
auto& values_in_level = answer.emplace_back();
vector<TreeNode*> nodes_in_next_level;
for (int i = nodes.size() - 1; i >= 0; i--) {
TreeNode* node = nodes[i];
values_in_level.push_back(node->val);
if (left_to_right) {
if (node->left) nodes_in_next_level.push_back(node->left);
if (node->right) nodes_in_next_level.push_back(node->right);
} else {
if (node->right) nodes_in_next_level.push_back(node->right);
if (node->left) nodes_in_next_level.push_back(node->left);
}
}
nodes = move(nodes_in_next_level);
left_to_right = !left_to_right;
}
return answer;
}
};