diff --git a/111/111. Minimum Depth of Binary Tree.md b/111/111. Minimum Depth of Binary Tree.md new file mode 100644 index 0000000..f040f43 --- /dev/null +++ b/111/111. Minimum Depth of Binary Tree.md @@ -0,0 +1,164 @@ +# [111. Minimum Depth of Binary Tree](https://leetcode.com/problems/minimum-depth-of-binary-tree/description/) +## Step1 +### 問題意図の考察 +- 問題文の確認 + - 2分木が与えられ、その最小の深さを見つけよ。 + - 最小の深さ:根nodeから最も近いleaf nodeまで到達するパスに含まれるノード数 + - 一昨日の問題で、「木の高さ・深さ」復習不足で明確に言葉にできなかった。反省。 + - 例2の場合、最小1で返せないのはleaf nodeではないからか + +- 制約の確認 + - The number of nodes in the tree is in the range [0, 10^5]. (100,000) + - -1000 <= Node.val <= 1000 + - 最大10万、O(n log n)でもいいが、O(n)がベター + +- 問題意図 + - rootから最も近いleaf nodeまでに含まれるnodeの数を返す. + - leaf nodeは、left == null AND right == null + +### 解法を考える。 +- maximumと同じようにDFS実行すると、勿体無いのでBFSで最小深さがいいのか +- DFSでもmin(minDepth(root->left), minDepth(root->right))で求められるのか + - これ片側nullの時、1を返してしまう気がする +- 分からなかったので、回答を見る。 + - https://github.com/5103246/LeetCode_Arai60/pull/21 + +初回の回答 +```cpp +#include +#include + +class Solution { + public: + int minDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + + std::queue> q; + q.emplace(root, 1); + + while (!q.empty()) { + auto [node, depth] = q.front(); + q.pop(); + + if (node->left == nullptr && node->right == nullptr) { + return depth; + } + + if (node->left != nullptr) { + q.emplace(node->left, depth + 1); + } + if (node->right != nullptr) { + q.emplace(node->right, depth + 1); + } + } + + return 0; + } +}; + +``` + +### コメント +- https://en.cppreference.com/w/cpp/container/queue.html + - queueの復習 以下コピー + +```cpp +#include +#include +#include + +int main() { + std::queue q; + + q.push(0); // back pushes 0 + q.push(1); // q = 0 1 + q.push(2); // q = 0 1 2 + q.push(3); // q = 0 1 2 3 + + assert(q.front() == 0); + assert(q.back() == 3); + assert(q.size() == 4); + + q.pop(); + assert(q.size() == 3); + + std::cout << "q: "; + for (; !q.empty(); q.pop()) + std::cout << q.front() << ' '; + std::cout << '\n'; + assert(q.size() == 0); +} + +``` + +## Step2 +- ドキュメント + - 構造化束縛に関して + - ドキュメントを確認したが、よく理解できなかった。 + - q.front()自体は参照だけど、一度[e]というローカル変数へコピーされる + - nodeとdepthはそのコピーeのメンバへの参照 + - queueの中身には結びついていない。こんな理解でいいのかな + - https://en.cppreference.com/w/cpp/language/structured_binding.html?utm_source + - https://devblogs.microsoft.com/oldnewthing/20201014-00/?p=104367&utm_source + - 日本語で再度確認 + - https://cpprefjp.github.io/lang/cpp17/structured_bindings.html?utm_source + + +- 他の方のコードを読む +- C++ + - https://github.com/nktr-cp/leetcode/pull/23/commits/89f89e3a299793d659c51608abb88ac78d1ad5e5 + - https://github.com/5103246/LeetCode_Arai60/pull/21/commits/91982dbf3d97e8cda66c9c98581a0c7fa6d41184 + - https://github.com/irohafternoon/LeetCode/pull/24/commits/dbfa048eee71878803336be5049cac289369f3d5 + +- Python + - https://github.com/nanae772/leetcode-arai60/pull/22/commits/b1014637825bd38227854616e206b4fb14a7da00#diff-c788c611274db6a06c7e00a85483754293185d8070e7b0ace89d2360e40d1fbb + +- 他の解法 +```cpp +#include + +class Solution { + public: + int minDepth(TreeNode* root) { + if (root == nullptr) { + return 0; + } + + std::vector current_nodes; + current_nodes.push_back(root); + int depth = 1; + + while (!current_nodes.empty()) { + std::vector next_nodes; + + for (TreeNode* node : current_nodes) { + if (node->left == nullptr && node->right == nullptr) { + return depth; + } + if (node->left != nullptr) { + next_nodes.push_back(node->left); + } + if (node->right != nullptr) { + next_nodes.push_back(node->right); + } + } + + ++depth; + current_nodes.swap(next_nodes); + } + + return 0; + } +}; + +``` + +## Step3 +1. 14min +2. 13min +3. 11min +4. 11min +5. 9min +