Skip to content

103. Binary Tree Zigzag Level Order Traversal #41

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

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
37 changes: 37 additions & 0 deletions 103/step1.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
/*

Solve Time : 11:48

Time : O(N)
Space : O(N)
*/
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
bool reversed_level = false;
vector<vector<int>> zigzag_level_ordered_vals;
vector<TreeNode*> current_level_nodes = {root};
while (!current_level_nodes.empty()) {
vector<TreeNode*> next_level_nodes;
vector<int> same_level_vals;
Copy link

Choose a reason for hiding this comment

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

currentとnextが対比で使われていて、それに対してsameというのがどっちと同じlevelなのか宣言時にわかりにくいため、自分ならcurrent_level_valsとします。

Copy link
Owner Author

Choose a reason for hiding this comment

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

なるほど、ありがとうございます。
current_level_nodesとの対比でわかりやすくなりますね

for (int i = 0; i < current_level_nodes.size(); ++i) {
if (!current_level_nodes[i]) {
continue;
}
same_level_vals.push_back(current_level_nodes[i]->val);
next_level_nodes.push_back(current_level_nodes[i]->left);
next_level_nodes.push_back(current_level_nodes[i]->right);
}
if (same_level_vals.empty()) {
Copy link

Choose a reason for hiding this comment

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

while (!current_level_nodes.empty()) { で空かどうかチェックしているため、この条件は不要だと思います。

Copy link

Choose a reason for hiding this comment

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

next_level_nodes.push_back(current_level_nodes[i]->left); で空ノードかどうか確認せずに入れているため、current_level_nodesの中身が全部空ノードの場合にsame_level_vals.empty()となると思います。

Copy link
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます。
ご指摘通りで、空配列をpush_backする可能性があるのでここでそれをケアしています。
が、そもそもそういうケアを入れなきゃいけないのは素直ではないですね・・・。

break;
}
if (reversed_level) {
reverse(same_level_vals.begin(), same_level_vals.end());
}
reversed_level = !reversed_level;
swap(current_level_nodes, next_level_nodes);
zigzag_level_ordered_vals.push_back(same_level_vals);
}
return zigzag_level_ordered_vals;
}
};
40 changes: 40 additions & 0 deletions 103/step2.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
Time: O(N)
Space: O(N)

nil判定を最初に置くことでwhileの条件やbreakを素直にした
*/
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
if (!root) {
return {};
}
bool reversed_level = false;
vector<vector<int>> zigzag_level_ordered_vals;
vector<TreeNode*> current_level_nodes = {root};
while (!current_level_nodes.empty()) {
vector<TreeNode*> next_level_nodes;
vector<int> same_level_vals;
for (int i = 0; i < current_level_nodes.size(); ++i) {
if (!current_level_nodes[i]) {
continue;
}
Comment on lines +20 to +22
Copy link

Choose a reason for hiding this comment

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

ここのチェックは使っていないという認識でいいですか。
下の if のほうを消して nullptr でも追加するという考え方でもいいですね。

Copy link
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます。
不使用コードでした、nullチェックの場所を色々弄ってたら消し忘れてしまったようです。

same_level_vals.push_back(current_level_nodes[i]->val);
if (current_level_nodes[i]->left) {
next_level_nodes.push_back(current_level_nodes[i]->left);
}
if (current_level_nodes[i]->right) {
next_level_nodes.push_back(current_level_nodes[i]->right);
}
}
if (reversed_level) {
Copy link

Choose a reason for hiding this comment

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

same_level_vals に関する処理と current_level_nodes, next_level_nodes に関する処理はまとめたほうが読みやすくなると思います。 same_level_vals を処理したあと、 current_level_nodes, next_level_nodes を処理してもう一度 same_level_vals を処理すると、 same_level_vals についてどのような処理を行ったのか、もう一度思い出さなければならなくなりますので。

Copy link
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます。
なるほど、確かに

        if (reversed_level) {
         reverse(same_level_vals.begin(), same_level_vals.end());
       }
       reversed_level = !reversed_level;
       zigzag_level_ordered_vals.push_back(same_level_vals);

       swap(current_level_nodes, next_level_nodes);

reverse(same_level_vals.begin(), same_level_vals.end());
}
reversed_level = !reversed_level;
swap(current_level_nodes, next_level_nodes);
zigzag_level_ordered_vals.push_back(same_level_vals);
}
return zigzag_level_ordered_vals;
}
};
32 changes: 32 additions & 0 deletions 103/step3.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
class Solution {
public:
vector<vector<int>> zigzagLevelOrder(TreeNode* root) {
if (!root) {
return {};
}
bool reverse_level = false;
Copy link

@olsen-blue olsen-blue Mar 2, 2025

Choose a reason for hiding this comment

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

変数名だけ見ると、数値かな?と見えそうです。
bool値であることが伝わるような、is_reverse_level など例えばいかがでしょうか。
is_at_reverse_level とかでもいいのかもしれません。

Copy link
Owner Author

Choose a reason for hiding this comment

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

なるほど、ありがとうございます、先頭にis_をつけるで良さそうですね。

vector<vector<int>> level_ordered_vals;
vector<TreeNode*> current_level_nodes = {root};
while (!current_level_nodes.empty()) {
vector<TreeNode*> next_level_nodes;
level_ordered_vals.push_back({});
Copy link

@olsen-blue olsen-blue Mar 2, 2025

Choose a reason for hiding this comment

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

C詳しくなく何とも言えませんが、push_back({})は何をしているのでしょうか?

Copy link

Choose a reason for hiding this comment

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

level_ordered_vals.append([]) と思えばだいたいいいです。

for (int i = 0; i < current_level_nodes.size(); ++i) {
Copy link

Choose a reason for hiding this comment

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

ranged for 使ってもいいかもしれませんね。

Copy link
Owner Author

Choose a reason for hiding this comment

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

コメントありがとうございます。
インデックスで要素にアクセスしないのでそちらの方が読みやすそうですね

auto node = current_level_nodes[i];
if (node->left) {
next_level_nodes.push_back(node->left);
}
if (node->right) {
next_level_nodes.push_back(node->right);
}
level_ordered_vals.back().push_back(node->val);
}
if (reverse_level) {
reverse(level_ordered_vals.back().begin(), level_ordered_vals.back().end());
}
reverse_level = !reverse_level;
swap(next_level_nodes, current_level_nodes);
}
return level_ordered_vals;
}
};