Skip to content

104. Maximum Depth of Binary Tree#4

Open
haniwachann wants to merge 3 commits intomasterfrom
06_Tree,BT,BST
Open

104. Maximum Depth of Binary Tree#4
haniwachann wants to merge 3 commits intomasterfrom
06_Tree,BT,BST

Conversation

@haniwachann
Copy link
Copy Markdown
Owner

参考にしたコードのリンクは貼っておく。
読みやすいことを意識する。
他の解法も考えみる。
計算量:O(N) 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.

時間と空間のどちらの計算量か明示すると良いと思います。

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.

ありがとうございます。
本問だと、空間(必要なメモリ)もO(N)でしょうか。


- 同じ高さのノードをwhileの中で全て調べ切れば、各ノードの深さをずっと覚えておく必要はない。

- もちろん再帰でも書ける。
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.

ありがとうございます!
再帰と幅優先探索でも解いて後ほどあげます!

}
current_node = root;
node_to_visit.push(current_node);
height[current_node] = 1;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

queueにdepthの情報を一緒に詰めてしまっても良いですね。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

1段ずつ下がっていく度にdepthを更新する方法もあるかもしれません。

pythonで恐縮ですが、ご参考。

from collections import deque


# Definition for a binary tree node.
# class TreeNode:
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution:
    def maxDepth(self, root: Optional[TreeNode]) -> int:
        if not root:
            return 0

        candidates = deque([(root)])
        depth = 0
        while candidates:
            depth += 1
            for _ in range(len(candidates)):    
                node = candidates.popleft()
                if node.left:
                    candidates.append(node.left)
                if node.right:
                    candidates.append(node.right)

        return depth

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

https://discord.com/channels/1084280443945353267/1303605021597761649/1306631474065309728
その書き方は candidates に同時に2種類のものが入っているので、個人的にはあまり好みではないですが、個人の趣味の範囲でしょう。

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.

すみません。
リンクに貼っていただいたコードは、「探索中(高さi)のノード」と「次(高さi+1)に探索するノード」を分けているという理解で良いでしょうか。

Comment on lines +17 to +18
TreeNode* left_node;
TreeNode* right_node;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

変数を作るのはいいんですが、スコープが広すぎるでしょう。

まず、初期化されていないので、読んだら未定義動作であることを警戒します。
そして、それが実際には使われている範囲が3行ずつなのだけれども、広いスコープにあるということはスコープを抜けても忘れてはいけないやつなのだろうと思い下の方まで保持し続けます。

ちなみに、古い C の流儀で、変数は上の方にまとめて宣言というのはありますが、現代的ではないかと思います。

current_node も
TreeNode* current_node = root;
と下で宣言したほうが親切でしょう。

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.

ありがとうございます。
変数が定義されてから、すぐに変数が出てきたほうが変数を覚えておく必要がなくなり読みやすくなると理解しました。

Comment on lines +70 to +72
if (root == nullptr){
return 0;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

私の趣味としては、これを一番上に持っていきます。

- step1でのrbegin()では必ずしも最大深さにはならないので、たどるノードの最大値を出すように修正

- pairはあまり使わないほうが良い
https://github.com/rossy0213/leetcode/pull/10#discussion_r1564630314
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

Choose a reason for hiding this comment

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

私は Java の Readablity Review で指摘されて、トラウマになっているため、やや過敏に反応してしまっています。

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

まあ、社内ではないので、そういう文化圏もあります、くらいでいいように思います。

class Solution {
public:
int maxDepth(TreeNode* root) {
TreeNode* current_node;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

個人的には、current_ がほとんど情報持っていないので、単に node でも読みやすさとしてはあまり変わらない、と思います。
https://discord.com/channels/1084280443945353267/1225849404037009609/1234218057199784077
のあたりですね。

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.

そうですね。役割がなにか次第でもあります。
https://discord.com/channels/1084280443945353267/1200089668901937312/1209882689411223644

map<TreeNode*, int> height;
queue<TreeNode*> node_to_visit;

current_node=root;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

代入演算子の両側にはスペースを 1 つずつ空けることをおすすめいたします。

https://google.github.io/styleguide/cppguide.html#Horizontal_Whitespace

Assignment operators always have spaces around them.

height[current_node] = 1;
node_to_visit.push(current_node);

while (current_node != nullptr && !node_to_visit.empty()) {
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

非 nullptr のポインターは、条件式として見たときに真となるため、個人的には while (current_node && !node_to_visit.empty()) { と書きます。ただ、人によってどちらが好きか、好みが分かれるかもしれません。

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.

ありがとうございます。
私も「current_nodeが存在すれば」という日本語を、コードにしようとしていたので、ご提案いただいた書き方のほうが自然だと思いました。

current_node = root;
node_to_visit.push(current_node);
height[current_node] = 1;
max_depth=0;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

height と depth を同じ意味で使っているように見えます。どちらかに統一したほうがシンプルになると思います。

- step1でのrbegin()では必ずしも最大深さにはならないので、たどるノードの最大値を出すように修正

- pairはあまり使わないほうが良い
https://github.com/rossy0213/leetcode/pull/10#discussion_r1564630314
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

私は Java の Readablity Review で指摘されて、トラウマになっているため、やや過敏に反応してしまっています。

TreeNode* current_node;
TreeNode* left_node;
TreeNode* right_node;
map<TreeNode*, int> height;
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Hashmapを使うという視点はなかったので、新鮮でした。

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.

5 participants