Sponsored
Sponsored
This approach uses a hash map to create nodes and establish their parent-child relationships. The root node is determined by finding nodes that haven't been a child in any relationship.
Time Complexity: O(N), where N is the number of descriptions.
Space Complexity: O(V), where V is the number of unique nodes.
1class TreeNode:
2 def __init__(self, val=0, left=None, right=None):
3 self.val = val
4 self.left = left
5 self.right = right
6
7class Solution:
8 def createBinaryTree(self, descriptions):
9 nodeMap = {}
10 children = set()
11
12 for parent, child, isLeft in descriptions:
13 if parent not in nodeMap:
14 nodeMap[parent] = TreeNode(parent)
15 if child not in nodeMap:
16 nodeMap[child] = TreeNode(child)
17
18 if isLeft:
19 nodeMap[parent].left = nodeMap[child]
20 else:
21 nodeMap[parent].right = nodeMap[child]
22
23 children.add(child)
24
25 # Find the root
26 for key in nodeMap:
27 if key not in children:
28 return nodeMap[key]
29
30 return None
31
The Python solution leverages a dictionary to track TreeNode instances and a set to identify nodes that have appeared as children. It iteratively constructs the tree based on the input descriptions, following direct mapping and reference updates.
This approach uses a two-pass algorithm: the first pass creates all nodes independently, and the second pass links them based on the descriptive relationships. This avoids simultaneous creation and linking, providing a clearer separation of concerns between node creation and linkage.
Time Complexity: O(N), where N is the number of descriptions.
Space Complexity: O(V), where V is the number of unique nodes.
1#include <unordered_set>
#include <vector>
using namespace std;
class TreeNode {
public:
int val;
TreeNode* left;
TreeNode* right;
TreeNode(int value) : val(value), left(nullptr), right(nullptr) {}
};
class Solution {
public:
TreeNode* createBinaryTree(vector<vector<int>>& descriptions) {
unordered_map<int, TreeNode*> nodes;
unordered_set<int> children;
// First pass to create all tree nodes
for (const auto& desc : descriptions) {
if (nodes.find(desc[0]) == nodes.end())
nodes[desc[0]] = new TreeNode(desc[0]);
if (nodes.find(desc[1]) == nodes.end())
nodes[desc[1]] = new TreeNode(desc[1]);
children.insert(desc[1]);
}
// Second pass to link tree nodes
for (const auto& desc : descriptions) {
int parent = desc[0], child = desc[1], isLeft = desc[2];
if (isLeft) {
nodes[parent]->left = nodes[child];
} else {
nodes[parent]->right = nodes[child];
}
}
for (const auto& [key, node] : nodes) {
if (children.find(key) == children.end()) {
return node;
}
}
return nullptr;
}
};
The C++ solution uses a two-pass algorithm similar to the C solution. The first pass initializes all nodes and records any child nodes. In the second pass, it establishes the prescribed left or right child relationships between the nodes.