๐ ์ด๋ณด์ ์นํ ๊ฐ์ด๋ โ๊ฐ์ฅ ๊น์ ๋ ธ๋๋ค์ ๋ชจ๋ ํฌํจํ๋ ๊ฐ์ฅ ์์ ์๋ธํธ๋ฆฌโ โ LeetCode 865 (C++, Python, JavaScript)
Source: Dev.to

๋ฌธ์ ์์ฝ
์ฃผ์ด์ง๋ ๊ฒ:
root์ด์ง ํธ๋ฆฌ์ ๋ฃจํธ.- ๋ค์ํ ๋ ๋ฒจ์ ์๋ ๋ ธ๋๋ค ์ค, โ๊ฐ์ฅ ๊น์โ ๋ ธ๋๋ ๋ฃจํธ์์ ๊ฐ์ฅ ๋ฉ๋ฆฌ ๋จ์ด์ง ๋ ธ๋์ด๋ค.
๋ชฉํ:
- ๊ทธ ๊ฐ์ฅ ๊น์ ๋ ธ๋๋ค์ ๋ชจ๋ ํฌํจํ๋ ๊ฐ์ฅ ์์ ์๋ธํธ๋ฆฌ๋ฅผ ์ฐพ๋๋ค. ๊ฐ์ฅ ๊น์ ๋ ธ๋๊ฐ ํ๋๋ฟ์ด๋ผ๋ฉด ๊ทธ ๋ ธ๋ ์์ฒด๊ฐ ๋ต์ด๋ค.
์ง๊ด
์ด ๋ฌธ์ ๋ฅผ ํด๊ฒฐํ๋ ค๋ฉด ๊ฐ ๋ ธ๋์ ๋ํด ๋ ๊ฐ์ง๋ฅผ ์์์ผ ํฉ๋๋ค: ์์๋ค์ ๊น์ด๊ฐ ์ผ๋ง๋ ๊น์๊ฐ? ๊ทธ๋ฆฌ๊ณ ๊ทธ๋ค์ ๊ณตํต ์กฐ์์ด ์ด๋ค ๋ ธ๋์ธ๊ฐ?
์ฌ๊ท์ ์ธ ๊น์ด ์ฐ์ ํ์(DFS) ๋ฐฉ์์ ์ฌ์ฉํฉ๋๋ค. ๋จ์ผ ๊ฐ์ ๋ฐํํ๋ ๋์ , ํจ์๋ ํ ์์ ๋ฐํํฉ๋๋ค: ํด๋น ์๋ธํธ๋ฆฌ์์ ๋๋ฌํ ๊ฐ์ฅ ๊น์ ๋ ๋ฒจ๊ณผ ์ต์ ๊ณตํต ์กฐ์ (LCA)์ ํ๋ณด ๋ ธ๋.
- ๊ธฐ๋ณธ ๊ฒฝ์ฐ: ๋
ธ๋๊ฐ
null์ด๋ฉด ๊น์ด๋0์ด๊ณ LCA๊ฐ ์์ต๋๋ค. - ์ฌ๊ท ๋จ๊ณ: ์ผ์ชฝ๊ณผ ์ค๋ฅธ์ชฝ ์์์ ์ต๋ ๊น์ด๋ฅผ ์กฐํํฉ๋๋ค.
- ์ผ์ชฝ์ด ๋ ๊น์ผ๋ฉด, ๊ฐ์ฅ ๊น์ ๋ ธ๋๋ค์ ์ผ์ชฝ ์๋ธํธ๋ฆฌ ์์๋ง ์กด์ฌํ๋ฏ๋ก ์ผ์ชฝ ๊ฒฐ๊ณผ๋ฅผ ์๋ก ์ ๋ฌํฉ๋๋ค.
- ์ค๋ฅธ์ชฝ์ด ๋ ๊น์ผ๋ฉด, ๊ฐ์ฅ ๊น์ ๋ ธ๋๋ค์ ์ค๋ฅธ์ชฝ ์๋ธํธ๋ฆฌ ์์๋ง ์กด์ฌํ๋ฏ๋ก ์ค๋ฅธ์ชฝ ๊ฒฐ๊ณผ๋ฅผ ์๋ก ์ ๋ฌํฉ๋๋ค.
- ๊น์ด๊ฐ ๊ฐ์ผ๋ฉด, ๊ฐ์ฅ ๊น์ ๋ ธ๋๋ค์ด ์ผ์ชฝ๊ณผ ์ค๋ฅธ์ชฝ ๊ฐ์ง์ ๋๋์ด ์์ผ๋ฏ๋ก ํ์ฌ ๋ ธ๋๊ฐ ์ด๋ฅผ ์ฐ๊ฒฐํ๋ ๊ฐ์ฅ ์์ ์๋ธํธ๋ฆฌ๊ฐ ๋ฉ๋๋ค.
์ฝ๋ ๋ธ๋ก
C++
struct Result {
TreeNode* lca;
int depth;
};
class Solution {
public:
TreeNode* subtreeWithAllDeepest(TreeNode* root) {
return dfs(root).lca;
}
private:
Result dfs(TreeNode* root) {
if (root == nullptr) return {nullptr, 0};
Result left = dfs(root->left);
Result right = dfs(root->right);
// If one side is deeper, the deepest nodes are exclusively there
if (left.depth > right.depth) {
return {left.lca, left.depth + 1};
}
if (left.depth // truncated line from original source
Python
class Solution:
def subtreeWithAllDeepest(self, root):
def dfs(node):
if not node:
return None, 0
left_lca, left_depth = dfs(node.left)
right_lca, right_depth = dfs(node.right)
if left_depth > right_depth:
return left_lca, left_depth + 1
if right_depth > left_depth:
return right_lca, right_depth + 1
# If depths are equal, current node is the LCA
return node, left_depth + 1
return dfs(root)[0]
JavaScript
var subtreeWithAllDeepest = function(root) {
const dfs = (node) => {
if (!node) return { lca: null, depth: 0 };
const left = dfs(node.left);
const right = dfs(node.right);
if (left.depth > right.depth) {
return { lca: left.lca, depth: left.depth + 1 };
}
if (right.depth > left.depth) {
return { lca: right.lca, depth: right.depth + 1 };
}
// If depths are equal, this node is the common ancestor
return { lca: node, depth: left.depth + 1 };
};
return dfs(root).lca;
};
ํต์ฌ ์์
- Postโorder Traversal: ์์ ๋ ธ๋๋ฅผ ๋ถ๋ชจ๋ณด๋ค ๋จผ์ ์ฒ๋ฆฌํ์ฌ ์ ์ฒด ์๋ธํธ๋ฆฌ ์ ๋ณด๋ฅผ ๊ธฐ๋ฐ์ผ๋ก ๊ฒฐ์ ์ ๋ด๋ฆด ์ ์์ต๋๋ค.
- Multiple Return Values: ๋ ธ๋์ ๊น์ด ๋ ๊ฐ์ ๋ฐํํจ์ผ๋ก์จ ์ค๋ณต๋ ํ์์ ํผํ๊ณ ์๊ณ ๋ฆฌ์ฆ์ ํจ์จ์ ์ผ๋ก ์ ์งํฉ๋๋ค.
- LCA Logic: ์ด ๋ฌธ์ ๋ ๊ณ ์ ์ ์ธ ์ต์ ๊ณตํต ์กฐ์(LCA) ๋ฌธ์ ์ ๋ณํ์ผ๋ก, โ๋์โ์ด ํน์ ๊ฐ์ด ์๋๋ผ ๊น์ด์ ๋ฐ๋ผ ๋์ ์ผ๋ก ์ ์๋ฉ๋๋ค.
์ต์ข ์๊ฐ
์ด ๋ฌธ์ ๋ ์ฌ๊ท์ ๋ณต์กํ ๋ฐํ ํ์ ์ ๋ค๋ฃจ๋ ๋ฅ๋ ฅ์ ํ ์คํธํ๊ธฐ ๋๋ฌธ์ ๊ธฐ์ ๋ฉด์ ์์ ์ธ๊ธฐ๊ฐ ๋ง์ต๋๋ค. ์ค์ ๋ก๋ ๋ ผ๋ฆฌ๊ฐ ๋ฐ์ดํฐ๋ฒ ์ด์ค ๊ณ์ธต ๊ตฌ์กฐ์์ โ๊ฐ์ฅ ๊ตฌ์ฒด์ ์ธ ๊ณตํต ์นดํ ๊ณ ๋ฆฌโ๋ฅผ ์ฐพ๊ฑฐ๋ ๋ณต์กํ ์์กด์ฑ ํธ๋ฆฌ์์ ๊ฐ์ฅ ์์ ๊ณต์ ๊ตฌ์ฑ ์์๋ฅผ ์๋ณํ๋ ๊ฒ๊ณผ ์ ์ฌํฉ๋๋ค. ๊ณ์ธตํ ๋ฐ์ดํฐ์ ์์ ํ๋ ๋ชจ๋ ์์ง๋์ด์๊ฒ ์ด ํํฅ์ ์ ๋ณด ํ๋ฆ์ ๋ง์คํฐํ๋ ๊ฒ์ด ํ์์ ์ ๋๋ค.