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.
1#include <unordered_map>
2#include <unordered_set>
3#include <vector>
4using namespace std;
5
6class TreeNode {
7public:
8 int val;
9 TreeNode* left;
10 TreeNode* right;
11 TreeNode(int value) : val(value), left(nullptr), right(nullptr) {}
12};
13
14class Solution {
15public:
16 TreeNode* createBinaryTree(vector<vector<int>>& descriptions) {
17 unordered_map<int, TreeNode*> nodes;
18 unordered_set<int> children;
19
20 for (const auto& desc : descriptions) {
21 int parent = desc[0], child = desc[1], isLeft = desc[2];
22 if (nodes.find(parent) == nodes.end())
23 nodes[parent] = new TreeNode(parent);
24 if (nodes.find(child) == nodes.end())
25 nodes[child] = new TreeNode(child);
26
27 if (isLeft) {
28 nodes[parent]->left = nodes[child];
29 } else {
30 nodes[parent]->right = nodes[child];
31 }
32
33 children.insert(child);
34 }
35
36 for (const auto& [key, node] : nodes) {
37 if (children.find(key) == children.end()) {
38 return node;
39 }
40 }
41
42 return nullptr;
43 }
44};
45
The C++ solution utilizes unordered_map to maintain mappings of node values to their TreeNode pointers. An unordered_set keeps track of all child nodes, and the tree is constructed by iterating over descriptions and linking the nodes.
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.
1using System.Collections.Generic;
public class TreeNode {
public int val;
public TreeNode left;
public TreeNode right;
public TreeNode(int val = 0, TreeNode left = null, TreeNode right = null) {
this.val = val;
this.left = left;
this.right = right;
}
}
public class Solution {
public TreeNode CreateBinaryTree(int[][] descriptions) {
Dictionary<int, TreeNode> nodeMap = new Dictionary<int, TreeNode>();
HashSet<int> children = new HashSet<int>();
// First pass: Create all nodes
foreach (var desc in descriptions) {
int parent = desc[0], child = desc[1];
if (!nodeMap.ContainsKey(parent))
nodeMap[parent] = new TreeNode(parent);
if (!nodeMap.ContainsKey(child))
nodeMap[child] = new TreeNode(child);
children.Add(child);
}
// Second pass: Link nodes
foreach (var desc in descriptions) {
int parent = desc[0], child = desc[1], isLeft = desc[2];
if (isLeft == 1) {
nodeMap[parent].left = nodeMap[child];
} else {
nodeMap[parent].right = nodeMap[child];
}
}
foreach (var key in nodeMap.Keys) {
if (!children.Contains(key)) {
return nodeMap[key];
}
}
return null;
}
}
The C# implementation employs a similar two-pass strategy. It maps each TreeNode to its value and marks children, using a second loop to build left and right mappings per description.