diff --git a/solution/2100-2199/2196.Create Binary Tree From Descriptions/README.md b/solution/2100-2199/2196.Create Binary Tree From Descriptions/README.md index 9f717e5ca0485..72463fd7b9217 100644 --- a/solution/2100-2199/2196.Create Binary Tree From Descriptions/README.md +++ b/solution/2100-2199/2196.Create Binary Tree From Descriptions/README.md @@ -73,7 +73,17 @@ tags: -### 方法一 +### 方法一:哈希表 + +我们可以用一个哈希表 $\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}$ 的长度。 @@ -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 @@ -125,26 +134,26 @@ class Solution: */ class Solution { public TreeNode createBinaryTree(int[][] descriptions) { - Map m = new HashMap<>(); - Set 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 nodes = new HashMap<>(); + Set 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 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; @@ -169,20 +178,27 @@ class Solution { class Solution { public: TreeNode* createBinaryTree(vector>& descriptions) { - unordered_map m; - unordered_set 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 nodes; + unordered_set 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; } @@ -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 @@ -248,63 +263,26 @@ func createBinaryTree(descriptions [][]int) *TreeNode { function createBinaryTree(descriptions: number[][]): TreeNode | null { const nodes: Record = {}; 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); - - 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 @@ -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) -> Option>> { - 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>) -> Option>> { - 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; + } + } +}; +``` + diff --git a/solution/2100-2199/2196.Create Binary Tree From Descriptions/README_EN.md b/solution/2100-2199/2196.Create Binary Tree From Descriptions/README_EN.md index ebf61f090da70..14cbe187ccd6e 100644 --- a/solution/2100-2199/2196.Create Binary Tree From Descriptions/README_EN.md +++ b/solution/2100-2199/2196.Create Binary Tree From Descriptions/README_EN.md @@ -68,7 +68,17 @@ The resulting binary tree is shown in the diagram. -### Solution 1 +### Solution 1: Hash Table + +We can use a hash table $\textit{nodes}$ to store all nodes, where the keys are the values of the nodes, and the values are the nodes themselves. Additionally, we use a set $\textit{children}$ to store all child nodes. + +We iterate through the $\textit{descriptions}$, and for each description $[\textit{parent}, \textit{child}, \textit{isLeft}]$, if $\textit{parent}$ is not in $\textit{nodes}$, we add $\textit{parent}$ to $\textit{nodes}$ and initialize a node with the value $\textit{parent}$. If $\textit{child}$ is not in $\textit{nodes}$, we add $\textit{child}$ to $\textit{nodes}$ and initialize a node with the value $\textit{child}$. Then, we add $\textit{child}$ to $\textit{children}$. + +If $\textit{isLeft}$ is true, we set $\textit{child}$ as the left child of $\textit{parent}$; otherwise, we set $\textit{child}$ as the right child of $\textit{parent}$. + +Finally, we iterate through $\textit{nodes}$, and if a node's value is not in $\textit{children}$, then this node is the root node, and we return this node. + +The time complexity is $O(n)$, and the space complexity is $O(n)$, where $n$ is the length of $\textit{descriptions}$. @@ -83,21 +93,20 @@ The resulting binary tree is shown in the diagram. # 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 @@ -120,26 +129,26 @@ class Solution: */ class Solution { public TreeNode createBinaryTree(int[][] descriptions) { - Map m = new HashMap<>(); - Set 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 nodes = new HashMap<>(); + Set 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 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; @@ -164,20 +173,27 @@ class Solution { class Solution { public: TreeNode* createBinaryTree(vector>& descriptions) { - unordered_map m; - unordered_set 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 nodes; + unordered_set 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; } @@ -196,27 +212,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 @@ -243,63 +258,26 @@ func createBinaryTree(descriptions [][]int) *TreeNode { function createBinaryTree(descriptions: number[][]): TreeNode | null { const nodes: Record = {}; 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); - - 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 @@ -324,49 +302,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) -> Option>> { - 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>) -> Option>> { - 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; + } + } +}; +``` + diff --git a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.cpp b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.cpp index d12c0cba56bfc..0d8588f7f937f 100644 --- a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.cpp +++ b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.cpp @@ -12,20 +12,27 @@ class Solution { public: TreeNode* createBinaryTree(vector>& descriptions) { - unordered_map m; - unordered_set 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 nodes; + unordered_set 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; } diff --git a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.go b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.go index 334b411af5f8c..31b0390dfb315 100644 --- a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.go +++ b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.go @@ -7,27 +7,26 @@ * } */ 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 diff --git a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.java b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.java index 75f78ca9afb28..8738d5125981a 100644 --- a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.java +++ b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.java @@ -15,26 +15,26 @@ */ class Solution { public TreeNode createBinaryTree(int[][] descriptions) { - Map m = new HashMap<>(); - Set 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 nodes = new HashMap<>(); + Set 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 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; diff --git a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.js b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.js index 82f519329a434..6e0112d2fc5da 100644 --- a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.js +++ b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.js @@ -10,25 +10,26 @@ * @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); - + 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); } - - 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]; }; diff --git a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.py b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.py index 5ba59d85c8339..919cb67b1c3a7 100644 --- a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.py +++ b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.py @@ -6,18 +6,17 @@ # 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] diff --git a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.rs b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.rs index 26f76b3b38919..7ae68c26d4097 100644 --- a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.rs +++ b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.rs @@ -17,44 +17,42 @@ // } // } 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) -> Option>> { - 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>) -> Option>> { - 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; - } - if !is_root.contains_key(&parent) { - is_root.insert(parent, true); + nodes.get(&parent).unwrap().borrow_mut().right = + Some(Rc::clone(nodes.get(&child).unwrap())); } - 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 } } diff --git a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.ts b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.ts index 57dd64c8a53c8..e87e7bf5f8ec1 100644 --- a/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.ts +++ b/solution/2100-2199/2196.Create Binary Tree From Descriptions/Solution.ts @@ -15,21 +15,23 @@ function createBinaryTree(descriptions: number[][]): TreeNode | null { const nodes: Record = {}; 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); - + 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); } - - 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]; } diff --git a/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/README.md b/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/README.md index 5f704610a9f14..7ef28fbbb5218 100644 --- a/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/README.md +++ b/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/README.md @@ -105,16 +105,16 @@ tags: ### 方法一:堆优化的 Dijkstra -我们先创建一个邻接表 $g$,用于存储图的边。然后创建一个数组 $dist$,用于存储从节点 $0$ 到其他节点的最短距离。初始化 $dist[0] = 0$,其余节点的距离初始化为无穷大。 +我们先创建一个邻接表 $\textit{g}$,用于存储图的边。然后创建一个数组 $\textit{dist}$,用于存储从节点 $0$ 到其他节点的最短距离。初始化 $\textit{dist}[0] = 0$,其余节点的距离初始化为无穷大。 然后,我们使用 Dijkstra 算法计算从节点 $0$ 到其他节点的最短距离。具体步骤如下: -1. 创建一个优先队列 $q$,用于存储节点的距离和节点编号,初始时将节点 $0$ 加入队列,距离为 $0$。 -2. 从队列中取出一个节点 $u$,如果 $u$ 的距离 $du$ 大于 $dist[u]$,说明 $u$ 已经被更新过了,直接跳过。 -3. 遍历节点 $u$ 的所有邻居节点 $v$,如果 $dist[v] > dist[u] + w$ 且 $dist[u] + w < disappear[v]$,则更新 $dist[v] = dist[u] + w$,并将节点 $v$ 加入队列。 +1. 创建一个优先队列 $\textit{pq}$,用于存储节点的距离和节点编号,初始时将节点 $0$ 加入队列,距离为 $0$。 +2. 从队列中取出一个节点 $u$,如果 $u$ 的距离 $du$ 大于 $\textit{dist}[u]$,说明 $u$ 已经被更新过了,直接跳过。 +3. 遍历节点 $u$ 的所有邻居节点 $v$,如果 $\textit{dist}[v] > \textit{dist}[u] + w$ 且 $\textit{dist}[u] + w < \textit{disappear}[v]$,则更新 $\textit{dist}[v] = \textit{dist}[u] + w$,并将节点 $v$ 加入队列。 4. 重复步骤 2 和步骤 3,直到队列为空。 -最后,我们遍历 $dist$ 数组,如果 $dist[i] < disappear[i]$,则 $answer[i] = dist[i]$,否则 $answer[i] = -1$。 +最后,我们遍历 $\textit{dist}$ 数组,如果 $\textit{dist}[i] < \textit{disappear}[i]$,则 $\textit{answer}[i] = \textit{dist}[i]$,否则 $\textit{answer}[i] = -1$。 时间复杂度 $O(m \times \log m)$,空间复杂度 $O(m)$。其中 $m$ 是边的数量。 @@ -289,6 +289,37 @@ func (h *hp) Push(v any) { *h = append(*h, v.(pair)) } func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v } ``` +#### TypeScript + +```ts +function minimumTime(n: number, edges: number[][], disappear: number[]): number[] { + const g: [number, number][][] = Array.from({ length: n }, () => []); + for (const [u, v, w] of edges) { + g[u].push([v, w]); + g[v].push([u, w]); + } + const dist = Array.from({ length: n }, () => Infinity); + dist[0] = 0; + const pq = new PriorityQueue({ + compare: (a, b) => (a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]), + }); + pq.enqueue([0, 0]); + while (pq.size() > 0) { + const [du, u] = pq.dequeue()!; + if (du > dist[u]) { + continue; + } + for (const [v, w] of g[u]) { + if (dist[v] > dist[u] + w && dist[u] + w < disappear[v]) { + dist[v] = dist[u] + w; + pq.enqueue([dist[v], v]); + } + } + } + return dist.map((a, i) => (a < disappear[i] ? a : -1)); +} +``` + diff --git a/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/README_EN.md b/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/README_EN.md index 9ba4b772101c8..08d820e5ab273 100644 --- a/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/README_EN.md +++ b/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/README_EN.md @@ -101,20 +101,20 @@ tags: -### Solution 1: Heap Optimized Dijkstra +### Solution 1: Heap-Optimized Dijkstra -First, we create an adjacency list $g$ to store the edges of the graph. Then we create an array $dist$ to store the shortest distance from node $0$ to other nodes. We initialize $dist[0] = 0$ and the distance of other nodes is initialized to infinity. +First, we create an adjacency list $\textit{g}$ to store the edges of the graph. Then, we create an array $\textit{dist}$ to store the shortest distances from node $0$ to other nodes. Initialize $\textit{dist}[0] = 0$, and the distances for the rest of the nodes are initialized to infinity. -Then, we use Dijkstra's algorithm to calculate the shortest distance from node $0$ to other nodes. The specific steps are as follows: +Next, we use the Dijkstra algorithm to calculate the shortest distances from node $0$ to other nodes. The specific steps are as follows: -1. Create a priority queue $q$ to store the distance and node number of nodes. Initially, add node $0$ to the queue with a distance of $0$. -2. Take out a node $u$ from the queue. If the distance $du$ of $u$ is greater than $dist[u]$, it means that $u$ has been updated, so skip it directly. -3. Traverse all neighbor nodes $v$ of node $u$. If $dist[v] > dist[u] + w$ and $dist[u] + w < disappear[v]$, then update $dist[v] = dist[u] + w$ and add node $v$ to the queue. +1. Create a priority queue $\textit{pq}$ to store the distances and node numbers. Initially, add node $0$ to the queue with a distance of $0$. +2. Remove a node $u$ from the queue. If the distance $du$ of $u$ is greater than $\textit{dist}[u]$, it means $u$ has already been updated, so we skip it directly. +3. Iterate through all neighbor nodes $v$ of node $u$. If $\textit{dist}[v] > \textit{dist}[u] + w$ and $\textit{dist}[u] + w < \textit{disappear}[v]$, then update $\textit{dist}[v] = \textit{dist}[u] + w$ and add node $v$ to the queue. 4. Repeat steps 2 and 3 until the queue is empty. -Finally, we traverse the $dist$ array. If $dist[i] < disappear[i]$, then $answer[i] = dist[i]$, otherwise $answer[i] = -1$. +Finally, we iterate through the $\textit{dist}$ array. If $\textit{dist}[i] < \textit{disappear}[i]$, then $\textit{answer}[i] = \textit{dist}[i]$; otherwise, $\textit{answer}[i] = -1$. -The time complexity is $O(m \times \log m)$, and the space complexity is $O(m)$, where $m$ is the number of edges. +The time complexity is $O(m \times \log m)$, and the space complexity is $O(m)$. Here, $m$ is the number of edges. @@ -287,6 +287,37 @@ func (h *hp) Push(v any) { *h = append(*h, v.(pair)) } func (h *hp) Pop() any { a := *h; v := a[len(a)-1]; *h = a[:len(a)-1]; return v } ``` +#### TypeScript + +```ts +function minimumTime(n: number, edges: number[][], disappear: number[]): number[] { + const g: [number, number][][] = Array.from({ length: n }, () => []); + for (const [u, v, w] of edges) { + g[u].push([v, w]); + g[v].push([u, w]); + } + const dist = Array.from({ length: n }, () => Infinity); + dist[0] = 0; + const pq = new PriorityQueue({ + compare: (a, b) => (a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]), + }); + pq.enqueue([0, 0]); + while (pq.size() > 0) { + const [du, u] = pq.dequeue()!; + if (du > dist[u]) { + continue; + } + for (const [v, w] of g[u]) { + if (dist[v] > dist[u] + w && dist[u] + w < disappear[v]) { + dist[v] = dist[u] + w; + pq.enqueue([dist[v], v]); + } + } + } + return dist.map((a, i) => (a < disappear[i] ? a : -1)); +} +``` + diff --git a/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/Solution.ts b/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/Solution.ts new file mode 100644 index 0000000000000..4751f7f563edd --- /dev/null +++ b/solution/3100-3199/3112.Minimum Time to Visit Disappearing Nodes/Solution.ts @@ -0,0 +1,26 @@ +function minimumTime(n: number, edges: number[][], disappear: number[]): number[] { + const g: [number, number][][] = Array.from({ length: n }, () => []); + for (const [u, v, w] of edges) { + g[u].push([v, w]); + g[v].push([u, w]); + } + const dist = Array.from({ length: n }, () => Infinity); + dist[0] = 0; + const pq = new PriorityQueue({ + compare: (a, b) => (a[0] === b[0] ? a[1] - b[1] : a[0] - b[0]), + }); + pq.enqueue([0, 0]); + while (pq.size() > 0) { + const [du, u] = pq.dequeue()!; + if (du > dist[u]) { + continue; + } + for (const [v, w] of g[u]) { + if (dist[v] > dist[u] + w && dist[u] + w < disappear[v]) { + dist[v] = dist[u] + w; + pq.enqueue([dist[v], v]); + } + } + } + return dist.map((a, i) => (a < disappear[i] ? a : -1)); +}