From 685f5922139c092dcbc5ae06761f7a6daed92294 Mon Sep 17 00:00:00 2001 From: yanglbme Date: Fri, 20 Oct 2023 20:28:18 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.2003 No.2003.Smallest Missing Genetic Value in Each Subtree --- .../README.md | 289 +++++++++++++++++- .../README_EN.md | 287 +++++++++++++++++ .../Solution.cpp | 44 +++ .../Solution.go | 41 +++ .../Solution.java | 50 +++ .../Solution.py | 34 +++ .../Solution.rs | 45 +++ .../Solution.ts | 39 +++ 8 files changed, 828 insertions(+), 1 deletion(-) create mode 100644 solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.cpp create mode 100644 solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.go create mode 100644 solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.java create mode 100644 solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.py create mode 100644 solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.rs create mode 100644 solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.ts diff --git a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/README.md b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/README.md index 7bcf4faae89f2..b4c5cdddd7626 100644 --- a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/README.md +++ b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/README.md @@ -69,6 +69,22 @@ +**方法一:DFS** + +我们注意到,每个节点的基因值互不相同,因此,我们只需要找到基因值为 $1$ 的节点 $idx$,那么除了从节点 $idx$ 到根节点 $0$ 的每个节点,其它节点的答案都是 $1$。 + +因此,我们初始化答案数组 $ans$ 为 $[1,1,...,1]$,然后我们的重点就在于求出节点 $idx$ 到根节点 $0$ 的路径上的每个节点的答案。 + +我们可以从节点 $idx$ 开始,通过深度优先搜索的方式,标记以 $idx$ 作为根节点的子树中出现过的基因值,记录在数组 $has$ 中。搜索过程中,我们用一个数组 $vis$ 标记已经访问过的节点,防止重复访问。 + +接下来,我们从 $i=2$ 开始,不断向后寻找第一个没有出现过的基因值,即为节点 $idx$ 的答案。这里 $i$ 是严格递增的,因为基因值互不相同,所以我们一定能在 $[1,..n+1]$ 中找到一个没有出现过的基因值。 + +然后,我们更新节点 $idx$ 的答案,即 $ans[idx]=i$,并将 $idx$ 更新为其父节点,继续上述过程,直到 $idx=-1$,即到达了根节点 $0$。 + +最后,我们返回答案数组 $ans$ 即可。 + +时间复杂度 $O(n)$,空间复杂度 $O(n)$。其中 $n$ 是节点的数量。 + ### **Python3** @@ -76,7 +92,40 @@ ```python - +class Solution: + def smallestMissingValueSubtree( + self, parents: List[int], nums: List[int] + ) -> List[int]: + def dfs(i: int): + if vis[i]: + return + vis[i] = True + if nums[i] < len(has): + has[nums[i]] = True + for j in g[i]: + dfs(j) + + n = len(nums) + ans = [1] * n + g = [[] for _ in range(n)] + idx = -1 + for i, p in enumerate(parents): + if i: + g[p].append(i) + if nums[i] == 1: + idx = i + if idx == -1: + return ans + vis = [False] * n + has = [False] * (n + 2) + i = 2 + while idx != -1: + dfs(idx) + while has[i]: + i += 1 + ans[idx] = i + idx = parents[idx] + return ans ``` ### **Java** @@ -84,7 +133,245 @@ ```java +class Solution { + private List[] g; + private boolean[] vis; + private boolean[] has; + private int[] nums; + + public int[] smallestMissingValueSubtree(int[] parents, int[] nums) { + int n = nums.length; + this.nums = nums; + g = new List[n]; + vis = new boolean[n]; + has = new boolean[n + 2]; + Arrays.setAll(g, i -> new ArrayList<>()); + int idx = -1; + for (int i = 0; i < n; ++i) { + if (i > 0) { + g[parents[i]].add(i); + } + if (nums[i] == 1) { + idx = i; + } + } + int[] ans = new int[n]; + Arrays.fill(ans, 1); + if (idx == -1) { + return ans; + } + for (int i = 2; idx != -1; idx = parents[idx]) { + dfs(idx); + while (has[i]) { + ++i; + } + ans[idx] = i; + } + return ans; + } + + private void dfs(int i) { + if (vis[i]) { + return; + } + vis[i] = true; + if (nums[i] < has.length) { + has[nums[i]] = true; + } + for (int j : g[i]) { + dfs(j); + } + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + vector smallestMissingValueSubtree(vector& parents, vector& nums) { + int n = nums.size(); + vector g[n]; + bool vis[n]; + bool has[n + 2]; + memset(vis, false, sizeof(vis)); + memset(has, false, sizeof(has)); + int idx = -1; + for (int i = 0; i < n; ++i) { + if (i) { + g[parents[i]].push_back(i); + } + if (nums[i] == 1) { + idx = i; + } + } + vector ans(n, 1); + if (idx == -1) { + return ans; + } + function dfs = [&](int i) { + if (vis[i]) { + return; + } + vis[i] = true; + if (nums[i] < n + 2) { + has[nums[i]] = true; + } + for (int j : g[i]) { + dfs(j); + } + }; + for (int i = 2; ~idx; idx = parents[idx]) { + dfs(idx); + while (has[i]) { + ++i; + } + ans[idx] = i; + } + return ans; + } +}; +``` + +### **Go** + +```go +func smallestMissingValueSubtree(parents []int, nums []int) []int { + n := len(nums) + g := make([][]int, n) + vis := make([]bool, n) + has := make([]bool, n+2) + idx := -1 + ans := make([]int, n) + for i, p := range parents { + if i > 0 { + g[p] = append(g[p], i) + } + if nums[i] == 1 { + idx = i + } + ans[i] = 1 + } + if idx < 0 { + return ans + } + var dfs func(int) + dfs = func(i int) { + if vis[i] { + return + } + vis[i] = true + if nums[i] < len(has) { + has[nums[i]] = true + } + for _, j := range g[i] { + dfs(j) + } + } + for i := 2; idx != -1; idx = parents[idx] { + dfs(idx) + for has[i] { + i++ + } + ans[idx] = i + } + return ans +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn smallest_missing_value_subtree(parents: Vec, nums: Vec) -> Vec { + fn dfs(i: usize, vis: &mut Vec, has: &mut Vec, g: &Vec>, nums: &Vec) { + if vis[i] { + return; + } + vis[i] = true; + if nums[i] < has.len() as i32 { + has[nums[i] as usize] = true; + } + for &j in &g[i] { + dfs(j, vis, has, g, nums); + } + } + + let n = nums.len(); + let mut ans = vec![1; n]; + let mut g: Vec> = vec![vec![]; n]; + let mut idx = -1; + for (i, &p) in parents.iter().enumerate() { + if i > 0 { + g[p as usize].push(i); + } + if nums[i] == 1 { + idx = i as i32; + } + } + if idx == -1 { + return ans; + } + let mut vis = vec![false; n]; + let mut has = vec![false; (n + 2) as usize]; + let mut i = 2; + let mut idx_mut = idx; + while idx_mut != -1 { + dfs(idx_mut as usize, &mut vis, &mut has, &g, &nums); + while has[i] { + i += 1; + } + ans[idx_mut as usize] = i as i32; + idx_mut = parents[idx_mut as usize]; + } + ans + } +} +``` +### **TypeScript** + +```ts +function smallestMissingValueSubtree(parents: number[], nums: number[]): number[] { + const n = nums.length; + const g: number[][] = Array.from({ length: n }, () => []); + const vis: boolean[] = Array(n).fill(false); + const has: boolean[] = Array(n + 2).fill(false); + const ans: number[] = Array(n).fill(1); + let idx = -1; + for (let i = 0; i < n; ++i) { + if (i) { + g[parents[i]].push(i); + } + if (nums[i] === 1) { + idx = i; + } + } + if (idx === -1) { + return ans; + } + const dfs = (i: number): void => { + if (vis[i]) { + return; + } + vis[i] = true; + if (nums[i] < has.length) { + has[nums[i]] = true; + } + for (const j of g[i]) { + dfs(j); + } + }; + for (let i = 2; ~idx; idx = parents[idx]) { + dfs(idx); + while (has[i]) { + ++i; + } + ans[idx] = i; + } + return ans; +} ``` ### **...** diff --git a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/README_EN.md b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/README_EN.md index f71db04951ff6..69627a06c403c 100644 --- a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/README_EN.md +++ b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/README_EN.md @@ -62,18 +62,305 @@ ## Solutions +**Solution 1: DFS** + +We notice that each node has a unique gene value, so we only need to find the node $idx$ with gene value $1$, and all nodes except for those on the path from node $idx$ to the root node $0$ have an answer of $1$. + +Therefore, we initialize the answer array $ans$ to $[1,1,...,1]$, and our focus is on finding the answer for each node on the path from node $idx$ to the root node $0$. + +We can start from node $idx$ and use depth-first search to mark the gene values that appear in the subtree rooted at $idx$, and record them in the array $has$. During the search process, we use an array $vis$ to mark the visited nodes to prevent repeated visits. + +Next, we start from $i=2$ and keep looking for the first gene value that has not appeared, which is the answer for node $idx$. Here, $i$ is strictly increasing, because the gene values are unique, so we can always find a gene value that has not appeared in $[1,..n+1]$. + +Then, we update the answer for node $idx$, i.e., $ans[idx]=i$, and update $idx$ to its parent node to continue the above process until $idx=-1$, which means we have reached the root node $0$. + +Finally, we return the answer array $ans$. + +The time complexity is $O(n)$, and the space complexity is $O(n)$. Here, $n$ is the number of nodes. + ### **Python3** ```python +class Solution: + def smallestMissingValueSubtree( + self, parents: List[int], nums: List[int] + ) -> List[int]: + def dfs(i: int): + if vis[i]: + return + vis[i] = True + if nums[i] < len(has): + has[nums[i]] = True + for j in g[i]: + dfs(j) + n = len(nums) + ans = [1] * n + g = [[] for _ in range(n)] + idx = -1 + for i, p in enumerate(parents): + if i: + g[p].append(i) + if nums[i] == 1: + idx = i + if idx == -1: + return ans + vis = [False] * n + has = [False] * (n + 2) + i = 2 + while idx != -1: + dfs(idx) + while has[i]: + i += 1 + ans[idx] = i + idx = parents[idx] + return ans ``` ### **Java** ```java +class Solution { + private List[] g; + private boolean[] vis; + private boolean[] has; + private int[] nums; + + public int[] smallestMissingValueSubtree(int[] parents, int[] nums) { + int n = nums.length; + this.nums = nums; + g = new List[n]; + vis = new boolean[n]; + has = new boolean[n + 2]; + Arrays.setAll(g, i -> new ArrayList<>()); + int idx = -1; + for (int i = 0; i < n; ++i) { + if (i > 0) { + g[parents[i]].add(i); + } + if (nums[i] == 1) { + idx = i; + } + } + int[] ans = new int[n]; + Arrays.fill(ans, 1); + if (idx == -1) { + return ans; + } + for (int i = 2; idx != -1; idx = parents[idx]) { + dfs(idx); + while (has[i]) { + ++i; + } + ans[idx] = i; + } + return ans; + } + + private void dfs(int i) { + if (vis[i]) { + return; + } + vis[i] = true; + if (nums[i] < has.length) { + has[nums[i]] = true; + } + for (int j : g[i]) { + dfs(j); + } + } +} +``` + +### **C++** + +```cpp +class Solution { +public: + vector smallestMissingValueSubtree(vector& parents, vector& nums) { + int n = nums.size(); + vector g[n]; + bool vis[n]; + bool has[n + 2]; + memset(vis, false, sizeof(vis)); + memset(has, false, sizeof(has)); + int idx = -1; + for (int i = 0; i < n; ++i) { + if (i) { + g[parents[i]].push_back(i); + } + if (nums[i] == 1) { + idx = i; + } + } + vector ans(n, 1); + if (idx == -1) { + return ans; + } + function dfs = [&](int i) { + if (vis[i]) { + return; + } + vis[i] = true; + if (nums[i] < n + 2) { + has[nums[i]] = true; + } + for (int j : g[i]) { + dfs(j); + } + }; + for (int i = 2; ~idx; idx = parents[idx]) { + dfs(idx); + while (has[i]) { + ++i; + } + ans[idx] = i; + } + return ans; + } +}; +``` + +### **Go** + +```go +func smallestMissingValueSubtree(parents []int, nums []int) []int { + n := len(nums) + g := make([][]int, n) + vis := make([]bool, n) + has := make([]bool, n+2) + idx := -1 + ans := make([]int, n) + for i, p := range parents { + if i > 0 { + g[p] = append(g[p], i) + } + if nums[i] == 1 { + idx = i + } + ans[i] = 1 + } + if idx < 0 { + return ans + } + var dfs func(int) + dfs = func(i int) { + if vis[i] { + return + } + vis[i] = true + if nums[i] < len(has) { + has[nums[i]] = true + } + for _, j := range g[i] { + dfs(j) + } + } + for i := 2; idx != -1; idx = parents[idx] { + dfs(idx) + for has[i] { + i++ + } + ans[idx] = i + } + return ans +} +``` + +### **Rust** + +```rust +impl Solution { + pub fn smallest_missing_value_subtree(parents: Vec, nums: Vec) -> Vec { + fn dfs(i: usize, vis: &mut Vec, has: &mut Vec, g: &Vec>, nums: &Vec) { + if vis[i] { + return; + } + vis[i] = true; + if nums[i] < has.len() as i32 { + has[nums[i] as usize] = true; + } + for &j in &g[i] { + dfs(j, vis, has, g, nums); + } + } + + let n = nums.len(); + let mut ans = vec![1; n]; + let mut g: Vec> = vec![vec![]; n]; + let mut idx = -1; + for (i, &p) in parents.iter().enumerate() { + if i > 0 { + g[p as usize].push(i); + } + if nums[i] == 1 { + idx = i as i32; + } + } + if idx == -1 { + return ans; + } + let mut vis = vec![false; n]; + let mut has = vec![false; (n + 2) as usize]; + let mut i = 2; + let mut idx_mut = idx; + while idx_mut != -1 { + dfs(idx_mut as usize, &mut vis, &mut has, &g, &nums); + while has[i] { + i += 1; + } + ans[idx_mut as usize] = i as i32; + idx_mut = parents[idx_mut as usize]; + } + ans + } +} +``` + +### **TypeScript** +```ts +function smallestMissingValueSubtree(parents: number[], nums: number[]): number[] { + const n = nums.length; + const g: number[][] = Array.from({ length: n }, () => []); + const vis: boolean[] = Array(n).fill(false); + const has: boolean[] = Array(n + 2).fill(false); + const ans: number[] = Array(n).fill(1); + let idx = -1; + for (let i = 0; i < n; ++i) { + if (i) { + g[parents[i]].push(i); + } + if (nums[i] === 1) { + idx = i; + } + } + if (idx === -1) { + return ans; + } + const dfs = (i: number): void => { + if (vis[i]) { + return; + } + vis[i] = true; + if (nums[i] < has.length) { + has[nums[i]] = true; + } + for (const j of g[i]) { + dfs(j); + } + }; + for (let i = 2; ~idx; idx = parents[idx]) { + dfs(idx); + while (has[i]) { + ++i; + } + ans[idx] = i; + } + return ans; +} ``` ### **...** diff --git a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.cpp b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.cpp new file mode 100644 index 0000000000000..1b537341d88b0 --- /dev/null +++ b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.cpp @@ -0,0 +1,44 @@ +class Solution { +public: + vector smallestMissingValueSubtree(vector& parents, vector& nums) { + int n = nums.size(); + vector g[n]; + bool vis[n]; + bool has[n + 2]; + memset(vis, false, sizeof(vis)); + memset(has, false, sizeof(has)); + int idx = -1; + for (int i = 0; i < n; ++i) { + if (i) { + g[parents[i]].push_back(i); + } + if (nums[i] == 1) { + idx = i; + } + } + vector ans(n, 1); + if (idx == -1) { + return ans; + } + function dfs = [&](int i) { + if (vis[i]) { + return; + } + vis[i] = true; + if (nums[i] < n + 2) { + has[nums[i]] = true; + } + for (int j : g[i]) { + dfs(j); + } + }; + for (int i = 2; ~idx; idx = parents[idx]) { + dfs(idx); + while (has[i]) { + ++i; + } + ans[idx] = i; + } + return ans; + } +}; \ No newline at end of file diff --git a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.go b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.go new file mode 100644 index 0000000000000..b94e11ad13da3 --- /dev/null +++ b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.go @@ -0,0 +1,41 @@ +func smallestMissingValueSubtree(parents []int, nums []int) []int { + n := len(nums) + g := make([][]int, n) + vis := make([]bool, n) + has := make([]bool, n+2) + idx := -1 + ans := make([]int, n) + for i, p := range parents { + if i > 0 { + g[p] = append(g[p], i) + } + if nums[i] == 1 { + idx = i + } + ans[i] = 1 + } + if idx < 0 { + return ans + } + var dfs func(int) + dfs = func(i int) { + if vis[i] { + return + } + vis[i] = true + if nums[i] < len(has) { + has[nums[i]] = true + } + for _, j := range g[i] { + dfs(j) + } + } + for i := 2; idx != -1; idx = parents[idx] { + dfs(idx) + for has[i] { + i++ + } + ans[idx] = i + } + return ans +} \ No newline at end of file diff --git a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.java b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.java new file mode 100644 index 0000000000000..147e270be32ef --- /dev/null +++ b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.java @@ -0,0 +1,50 @@ +class Solution { + private List[] g; + private boolean[] vis; + private boolean[] has; + private int[] nums; + + public int[] smallestMissingValueSubtree(int[] parents, int[] nums) { + int n = nums.length; + this.nums = nums; + g = new List[n]; + vis = new boolean[n]; + has = new boolean[n + 2]; + Arrays.setAll(g, i -> new ArrayList<>()); + int idx = -1; + for (int i = 0; i < n; ++i) { + if (i > 0) { + g[parents[i]].add(i); + } + if (nums[i] == 1) { + idx = i; + } + } + int[] ans = new int[n]; + Arrays.fill(ans, 1); + if (idx == -1) { + return ans; + } + for (int i = 2; idx != -1; idx = parents[idx]) { + dfs(idx); + while (has[i]) { + ++i; + } + ans[idx] = i; + } + return ans; + } + + private void dfs(int i) { + if (vis[i]) { + return; + } + vis[i] = true; + if (nums[i] < has.length) { + has[nums[i]] = true; + } + for (int j : g[i]) { + dfs(j); + } + } +} \ No newline at end of file diff --git a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.py b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.py new file mode 100644 index 0000000000000..2f3ffd9114ac3 --- /dev/null +++ b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.py @@ -0,0 +1,34 @@ +class Solution: + def smallestMissingValueSubtree( + self, parents: List[int], nums: List[int] + ) -> List[int]: + def dfs(i: int): + if vis[i]: + return + vis[i] = True + if nums[i] < len(has): + has[nums[i]] = True + for j in g[i]: + dfs(j) + + n = len(nums) + ans = [1] * n + g = [[] for _ in range(n)] + idx = -1 + for i, p in enumerate(parents): + if i: + g[p].append(i) + if nums[i] == 1: + idx = i + if idx == -1: + return ans + vis = [False] * n + has = [False] * (n + 2) + i = 2 + while idx != -1: + dfs(idx) + while has[i]: + i += 1 + ans[idx] = i + idx = parents[idx] + return ans diff --git a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.rs b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.rs new file mode 100644 index 0000000000000..ef09d47ae102d --- /dev/null +++ b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.rs @@ -0,0 +1,45 @@ +impl Solution { + pub fn smallest_missing_value_subtree(parents: Vec, nums: Vec) -> Vec { + fn dfs(i: usize, vis: &mut Vec, has: &mut Vec, g: &Vec>, nums: &Vec) { + if vis[i] { + return; + } + vis[i] = true; + if nums[i] < has.len() as i32 { + has[nums[i] as usize] = true; + } + for &j in &g[i] { + dfs(j, vis, has, g, nums); + } + } + + let n = nums.len(); + let mut ans = vec![1; n]; + let mut g: Vec> = vec![vec![]; n]; + let mut idx = -1; + for (i, &p) in parents.iter().enumerate() { + if i > 0 { + g[p as usize].push(i); + } + if nums[i] == 1 { + idx = i as i32; + } + } + if idx == -1 { + return ans; + } + let mut vis = vec![false; n]; + let mut has = vec![false; (n + 2) as usize]; + let mut i = 2; + let mut idx_mut = idx; + while idx_mut != -1 { + dfs(idx_mut as usize, &mut vis, &mut has, &g, &nums); + while has[i] { + i += 1; + } + ans[idx_mut as usize] = i as i32; + idx_mut = parents[idx_mut as usize]; + } + ans + } +} \ No newline at end of file diff --git a/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.ts b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.ts new file mode 100644 index 0000000000000..f97cc5bcdadf1 --- /dev/null +++ b/solution/2000-2099/2003.Smallest Missing Genetic Value in Each Subtree/Solution.ts @@ -0,0 +1,39 @@ +function smallestMissingValueSubtree(parents: number[], nums: number[]): number[] { + const n = nums.length; + const g: number[][] = Array.from({ length: n }, () => []); + const vis: boolean[] = Array(n).fill(false); + const has: boolean[] = Array(n + 2).fill(false); + const ans: number[] = Array(n).fill(1); + let idx = -1; + for (let i = 0; i < n; ++i) { + if (i) { + g[parents[i]].push(i); + } + if (nums[i] === 1) { + idx = i; + } + } + if (idx === -1) { + return ans; + } + const dfs = (i: number): void => { + if (vis[i]) { + return; + } + vis[i] = true; + if (nums[i] < has.length) { + has[nums[i]] = true; + } + for (const j of g[i]) { + dfs(j); + } + }; + for (let i = 2; ~idx; idx = parents[idx]) { + dfs(idx); + while (has[i]) { + ++i; + } + ans[idx] = i; + } + return ans; +}