Skip to content

feat: update solutions to lc problem: No.2196,3112 #3276

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Jul 16, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
296 changes: 156 additions & 140 deletions solution/2100-2199/2196.Create Binary Tree From Descriptions/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -73,7 +73,17 @@ tags:

<!-- solution:start -->

### 方法一
### 方法一:哈希表

我们可以用一个哈希表 $\textit{nodes}$ 来存储所有节点,其中键为节点的值,值为节点本身,用一个集合 $\textit{children}$ 来存储所有的子节点。

遍历 $\textit{descriptions}$,对于每个描述 $[\textit{parent}, \textit{child}, \textit{isLeft}]$,如果 $\textit{parent}$ 不在 $\textit{nodes}$ 中,我们就将 $\textit{parent}$ 加入 $\textit{nodes}$,并初始化一个值为 $\textit{parent}$ 的节点。如果 $\textit{child}$ 不在 $\textit{nodes}$ 中,我们就将 $\textit{child}$ 加入 $\textit{nodes}$,并初始化一个值为 $\textit{child}$ 的节点。然后我们将 $\textit{child}$ 加入 $\textit{children}$。

如果 $\textit{isLeft}$ 为真,我们就将 $\textit{child}$ 作为 $\textit{parent}$ 的左子节点,否则我们就将 $\textit{child}$ 作为 $\textit{parent}$ 的右子节点。

最后,我们遍历 $\textit{nodes}$,如果某个节点的值不在 $\textit{children}$ 中,那么这个节点就是根节点,我们返回这个节点。

时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是 $\textit{descriptions}$ 的长度。

<!-- tabs:start -->

Expand All @@ -88,21 +98,20 @@ tags:
# self.right = right
class Solution:
def createBinaryTree(self, descriptions: List[List[int]]) -> Optional[TreeNode]:
g = defaultdict(TreeNode)
vis = set()
for p, c, left in descriptions:
if p not in g:
g[p] = TreeNode(p)
if c not in g:
g[c] = TreeNode(c)
if left:
g[p].left = g[c]
nodes = defaultdict(TreeNode)
children = set()
for parent, child, isLeft in descriptions:
if parent not in nodes:
nodes[parent] = TreeNode(parent)
if child not in nodes:
nodes[child] = TreeNode(child)
children.add(child)
if isLeft:
nodes[parent].left = nodes[child]
else:
g[p].right = g[c]
vis.add(c)
for v, node in g.items():
if v not in vis:
return node
nodes[parent].right = nodes[child]
root = (set(nodes.keys()) - children).pop()
return nodes[root]
```

#### Java
Expand All @@ -125,26 +134,26 @@ class Solution:
*/
class Solution {
public TreeNode createBinaryTree(int[][] descriptions) {
Map<Integer, TreeNode> m = new HashMap<>();
Set<Integer> vis = new HashSet<>();
for (int[] d : descriptions) {
int p = d[0], c = d[1], isLeft = d[2];
if (!m.containsKey(p)) {
m.put(p, new TreeNode(p));
Map<Integer, TreeNode> nodes = new HashMap<>();
Set<Integer> children = new HashSet<>();
for (var d : descriptions) {
int parent = d[0], child = d[1], isLeft = d[2];
if (!nodes.containsKey(parent)) {
nodes.put(parent, new TreeNode(parent));
}
if (!m.containsKey(c)) {
m.put(c, new TreeNode(c));
if (!nodes.containsKey(child)) {
nodes.put(child, new TreeNode(child));
}
if (isLeft == 1) {
m.get(p).left = m.get(c);
nodes.get(parent).left = nodes.get(child);
} else {
m.get(p).right = m.get(c);
nodes.get(parent).right = nodes.get(child);
}
vis.add(c);
children.add(child);
}
for (Map.Entry<Integer, TreeNode> entry : m.entrySet()) {
if (!vis.contains(entry.getKey())) {
return entry.getValue();
for (var e : nodes.entrySet()) {
if (!children.contains(e.getKey())) {
return e.getValue();
}
}
return null;
Expand All @@ -169,20 +178,27 @@ class Solution {
class Solution {
public:
TreeNode* createBinaryTree(vector<vector<int>>& descriptions) {
unordered_map<int, TreeNode*> m;
unordered_set<int> vis;
for (auto& d : descriptions) {
int p = d[0], c = d[1], left = d[2];
if (!m.count(p)) m[p] = new TreeNode(p);
if (!m.count(c)) m[c] = new TreeNode(c);
if (left)
m[p]->left = m[c];
else
m[p]->right = m[c];
vis.insert(c);
unordered_map<int, TreeNode*> nodes;
unordered_set<int> children;
for (const auto& d : descriptions) {
int parent = d[0], child = d[1], isLeft = d[2];
if (!nodes.contains(parent)) {
nodes[parent] = new TreeNode(parent);
}
if (!nodes.contains(child)) {
nodes[child] = new TreeNode(child);
}
if (isLeft) {
nodes[parent]->left = nodes[child];
} else {
nodes[parent]->right = nodes[child];
}
children.insert(child);
}
for (auto& [v, node] : m) {
if (!vis.count(v)) return node;
for (const auto& [k, v] : nodes) {
if (!children.contains(k)) {
return v;
}
}
return nullptr;
}
Expand All @@ -201,27 +217,26 @@ public:
* }
*/
func createBinaryTree(descriptions [][]int) *TreeNode {
m := make(map[int]*TreeNode)
vis := make(map[int]bool)
nodes := map[int]*TreeNode{}
children := map[int]bool{}
for _, d := range descriptions {
p, c, left := d[0], d[1], d[2]
if m[p] == nil {
m[p] = &TreeNode{Val: p}
parent, child, isLeft := d[0], d[1], d[2]
if _, ok := nodes[parent]; !ok {
nodes[parent] = &TreeNode{Val: parent}
}
if m[c] == nil {
m[c] = &TreeNode{Val: c}
if _, ok := nodes[child]; !ok {
nodes[child] = &TreeNode{Val: child}
}
if left == 1 {
m[p].Left = m[c]
if isLeft == 1 {
nodes[parent].Left = nodes[child]
} else {
m[p].Right = m[c]
nodes[parent].Right = nodes[child]
}
vis[c] = true
children[child] = true
}

for v, node := range m {
if !vis[v] {
return node
for k, v := range nodes {
if _, ok := children[k]; !ok {
return v
}
}
return nil
Expand All @@ -248,63 +263,26 @@ func createBinaryTree(descriptions [][]int) *TreeNode {
function createBinaryTree(descriptions: number[][]): TreeNode | null {
const nodes: Record<number, TreeNode> = {};
const children = new Set<number>();

for (const [parent, child] of descriptions) {
if (!nodes[parent]) nodes[parent] = new TreeNode(parent);
if (!nodes[child]) nodes[child] = new TreeNode(child);

children.add(child);
}

let root = -1;
for (const [parent, child, isLeft] of descriptions) {
if (!children.has(parent)) root = parent;

if (isLeft) nodes[parent].left = nodes[child];
else nodes[parent].right = nodes[child];
}

return nodes[root];
}
```

#### JavaScript

```js
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {number[][]} descriptions
* @return {TreeNode}
*/

var createBinaryTree = function (descriptions) {
const nodes = {};
const children = new Set();

for (const [parent, child] of descriptions) {
if (!nodes[parent]) nodes[parent] = new TreeNode(parent);
if (!nodes[child]) nodes[child] = new TreeNode(child);

if (!nodes[parent]) {
nodes[parent] = new TreeNode(parent);
}
if (!nodes[child]) {
nodes[child] = new TreeNode(child);
}
if (isLeft) {
nodes[parent].left = nodes[child];
} else {
nodes[parent].right = nodes[child];
}
children.add(child);
}

let root = -1;
for (const [parent, child, isLeft] of descriptions) {
if (!children.has(parent)) root = parent;

if (isLeft) nodes[parent].left = nodes[child];
else nodes[parent].right = nodes[child];
for (const [k, v] of Object.entries(nodes)) {
if (!children.has(+k)) {
return v;
}
}

return nodes[root];
};
}
```

#### Rust
Expand All @@ -329,49 +307,87 @@ var createBinaryTree = function (descriptions) {
// }
// }
use std::cell::RefCell;
use std::collections::HashMap;
use std::collections::{HashMap, HashSet};
use std::rc::Rc;
impl Solution {
fn dfs(val: i32, map: &HashMap<i32, [i32; 2]>) -> Option<Rc<RefCell<TreeNode>>> {
if val == 0 {
return None;
}
let mut left = None;
let mut right = None;
if let Some(&[l_val, r_val]) = map.get(&val) {
left = Self::dfs(l_val, map);
right = Self::dfs(r_val, map);
}
Some(Rc::new(RefCell::new(TreeNode { val, left, right })))
}

pub fn create_binary_tree(descriptions: Vec<Vec<i32>>) -> Option<Rc<RefCell<TreeNode>>> {
let mut map = HashMap::new();
let mut is_root = HashMap::new();
for description in descriptions.iter() {
let (parent, child, is_left) = (description[0], description[1], description[2] == 1);
let [mut left, mut right] = map.get(&parent).unwrap_or(&[0, 0]);
if is_left {
left = child;
let mut nodes = HashMap::new();
let mut children = HashSet::new();

for d in descriptions {
let parent = d[0];
let child = d[1];
let is_left = d[2];

nodes
.entry(parent)
.or_insert_with(|| Rc::new(RefCell::new(TreeNode::new(parent))));
nodes
.entry(child)
.or_insert_with(|| Rc::new(RefCell::new(TreeNode::new(child))));

if is_left == 1 {
nodes.get(&parent).unwrap().borrow_mut().left =
Some(Rc::clone(nodes.get(&child).unwrap()));
} else {
right = child;
nodes.get(&parent).unwrap().borrow_mut().right =
Some(Rc::clone(nodes.get(&child).unwrap()));
}
if !is_root.contains_key(&parent) {
is_root.insert(parent, true);
}
is_root.insert(child, false);
map.insert(parent, [left, right]);

children.insert(child);
}
for key in is_root.keys() {
if *is_root.get(key).unwrap() {
return Self::dfs(*key, &map);

for (key, node) in &nodes {
if !children.contains(key) {
return Some(Rc::clone(node));
}
}

None
}
}
```

#### JavaScript

```js
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
*/
/**
* @param {number[][]} descriptions
* @return {TreeNode}
*/
var createBinaryTree = function (descriptions) {
const nodes = {};
const children = new Set();
for (const [parent, child, isLeft] of descriptions) {
if (!nodes[parent]) {
nodes[parent] = new TreeNode(parent);
}
if (!nodes[child]) {
nodes[child] = new TreeNode(child);
}
if (isLeft) {
nodes[parent].left = nodes[child];
} else {
nodes[parent].right = nodes[child];
}
children.add(child);
}
for (const [k, v] of Object.entries(nodes)) {
if (!children.has(+k)) {
return v;
}
}
};
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Loading
Loading