Skip to content

Commit d81e053

Browse files
committed
feat: add solutions to lc problem: No.1519
No.1519.Number of Nodes in the Sub-Tree With the Same Label
1 parent 96d78ae commit d81e053

File tree

9 files changed

+345
-6
lines changed

9 files changed

+345
-6
lines changed

Diff for: solution/1500-1599/1518.Water Bottles/README.md

+12-2
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,17 @@
5151

5252
<!-- 这里可写通用的实现逻辑 -->
5353

54-
直接模拟空瓶兑新酒即可。
54+
**方法一:模拟**
55+
56+
我们可以直接模拟整个过程。
57+
58+
初始时,我们有 `numBottles` 瓶水,因此可以喝到 `ans = numBottles` 瓶水,然后得到 `numBottles` 个空瓶子。
59+
60+
接下来,如果我们有 `numExchange` 个空瓶子,那么我们可以用它们兑换一瓶水并喝掉,此时我们剩余的空瓶子数量为 `numBottles - numExchange + 1`,然后我们累加喝到的水的数量,即 $ans = ans + 1$。
61+
62+
最后,返回 `ans` 即可。
63+
64+
时间复杂度 $(\frac{numBottles}{numExchange})$,空间复杂度 $O(1)$。
5565

5666
<!-- tabs:start -->
5767

@@ -64,7 +74,7 @@ class Solution:
6474
def numWaterBottles(self, numBottles: int, numExchange: int) -> int:
6575
ans = numBottles
6676
while numBottles >= numExchange:
67-
numBottles -= numExchange - 1
77+
numBottles -= (numExchange - 1)
6878
ans += 1
6979
return ans
7080
```

Diff for: solution/1500-1599/1518.Water Bottles/README_EN.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class Solution:
4848
def numWaterBottles(self, numBottles: int, numExchange: int) -> int:
4949
ans = numBottles
5050
while numBottles >= numExchange:
51-
numBottles -= numExchange - 1
51+
numBottles -= (numExchange - 1)
5252
ans += 1
5353
return ans
5454
```

Diff for: solution/1500-1599/1518.Water Bottles/Solution.py

+1-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,6 @@ class Solution:
22
def numWaterBottles(self, numBottles: int, numExchange: int) -> int:
33
ans = numBottles
44
while numBottles >= numExchange:
5-
numBottles -= numExchange - 1
5+
numBottles -= (numExchange - 1)
66
ans += 1
77
return ans

Diff for: solution/1500-1599/1519.Number of Nodes in the Sub-Tree With the Same Label/README.md

+120-1
Original file line numberDiff line numberDiff line change
@@ -67,22 +67,141 @@
6767

6868
<!-- 这里可写通用的实现逻辑 -->
6969

70+
**方法一:DFS**
71+
72+
我们先将边数组转换为邻接表 $g$。
73+
74+
接下来我们从根节点 $0$ 开始遍历其子树,过程中维护一个计数器 $cnt$,用于统计当前各个字母出现的次数。
75+
76+
在访问某个节点 $i$ 时,我们先将 $ans[i]$ 减去 $cnt[labels[i]]$,然后将 $cnt[labels[i]]$ 加 $1$,表示当前节点 $i$ 的标签出现了一次。接下来递归访问其子节点,最后将 $ans[i]$ 加上 $cnt[labels[i]]$。也即是说,我们将每个点离开时的计数器值减去每个点进来时的计数器值,就得到了以该点为根的子树中各个字母出现的次数。
77+
78+
时间复杂度 $O(n)$,空间复杂度 $O(C)$。其中 $n$ 为节点数;而 $C$ 为字符集大小,本题中 $C = 26$。
79+
7080
<!-- tabs:start -->
7181

7282
### **Python3**
7383

7484
<!-- 这里可写当前语言的特殊实现逻辑 -->
7585

7686
```python
77-
87+
class Solution:
88+
def countSubTrees(self, n: int, edges: List[List[int]], labels: str) -> List[int]:
89+
def dfs(i, fa):
90+
ans[i] -= cnt[labels[i]]
91+
cnt[labels[i]] += 1
92+
for j in g[i]:
93+
if j != fa:
94+
dfs(j, i)
95+
ans[i] += cnt[labels[i]]
96+
97+
g = defaultdict(list)
98+
for a, b in edges:
99+
g[a].append(b)
100+
g[b].append(a)
101+
cnt = Counter()
102+
ans = [0] * n
103+
dfs(0, -1)
104+
return ans
78105
```
79106

80107
### **Java**
81108

82109
<!-- 这里可写当前语言的特殊实现逻辑 -->
83110

84111
```java
112+
class Solution {
113+
private List<Integer>[] g;
114+
private String labels;
115+
private int[] ans;
116+
private int[] cnt;
117+
118+
public int[] countSubTrees(int n, int[][] edges, String labels) {
119+
g = new List[n];
120+
Arrays.setAll(g, k -> new ArrayList<>());
121+
for (int[] e : edges) {
122+
int a = e[0], b = e[1];
123+
g[a].add(b);
124+
g[b].add(a);
125+
}
126+
this.labels = labels;
127+
ans = new int[n];
128+
cnt = new int[26];
129+
dfs(0, -1);
130+
return ans;
131+
}
132+
133+
private void dfs(int i, int fa) {
134+
int k = labels.charAt(i) - 'a';
135+
ans[i] -= cnt[k];
136+
cnt[k]++;
137+
for (int j : g[i]) {
138+
if (j != fa) {
139+
dfs(j, i);
140+
}
141+
}
142+
ans[i] += cnt[k];
143+
}
144+
}
145+
```
146+
147+
### **C++**
148+
149+
```cpp
150+
class Solution {
151+
public:
152+
vector<int> countSubTrees(int n, vector<vector<int>>& edges, string labels) {
153+
vector<vector<int>> g(n);
154+
for (auto& e : edges) {
155+
int a = e[0], b = e[1];
156+
g[a].push_back(b);
157+
g[b].push_back(a);
158+
}
159+
vector<int> ans(n);
160+
int cnt[26]{};
161+
function<void(int, int)> dfs = [&](int i, int fa) {
162+
int k = labels[i] - 'a';
163+
ans[i] -= cnt[k];
164+
cnt[k]++;
165+
for (int& j : g[i]) {
166+
if (j != fa) {
167+
dfs(j, i);
168+
}
169+
}
170+
ans[i] += cnt[k];
171+
};
172+
dfs(0, -1);
173+
return ans;
174+
}
175+
};
176+
```
85177
178+
### **Go**
179+
180+
```go
181+
func countSubTrees(n int, edges [][]int, labels string) []int {
182+
g := make([][]int, n)
183+
for _, e := range edges {
184+
a, b := e[0], e[1]
185+
g[a] = append(g[a], b)
186+
g[b] = append(g[b], a)
187+
}
188+
ans := make([]int, n)
189+
cnt := [26]int{}
190+
var dfs func(int, int)
191+
dfs = func(i, fa int) {
192+
k := labels[i] - 'a'
193+
ans[i] -= cnt[k]
194+
cnt[k]++
195+
for _, j := range g[i] {
196+
if j != fa {
197+
dfs(j, i)
198+
}
199+
}
200+
ans[i] += cnt[k]
201+
}
202+
dfs(0, -1)
203+
return ans
204+
}
86205
```
87206

88207
### **...**

Diff for: solution/1500-1599/1519.Number of Nodes in the Sub-Tree With the Same Label/README_EN.md

+110-1
Original file line numberDiff line numberDiff line change
@@ -60,13 +60,122 @@ The sub-tree of node 0 contains nodes 0, 1, 2 and 3, all with label &#39;b&#39;,
6060
### **Python3**
6161

6262
```python
63-
63+
class Solution:
64+
def countSubTrees(self, n: int, edges: List[List[int]], labels: str) -> List[int]:
65+
def dfs(i, fa):
66+
ans[i] -= cnt[labels[i]]
67+
cnt[labels[i]] += 1
68+
for j in g[i]:
69+
if j != fa:
70+
dfs(j, i)
71+
ans[i] += cnt[labels[i]]
72+
73+
g = defaultdict(list)
74+
for a, b in edges:
75+
g[a].append(b)
76+
g[b].append(a)
77+
cnt = Counter()
78+
ans = [0] * n
79+
dfs(0, -1)
80+
return ans
6481
```
6582

6683
### **Java**
6784

6885
```java
86+
class Solution {
87+
private List<Integer>[] g;
88+
private String labels;
89+
private int[] ans;
90+
private int[] cnt;
91+
92+
public int[] countSubTrees(int n, int[][] edges, String labels) {
93+
g = new List[n];
94+
Arrays.setAll(g, k -> new ArrayList<>());
95+
for (int[] e : edges) {
96+
int a = e[0], b = e[1];
97+
g[a].add(b);
98+
g[b].add(a);
99+
}
100+
this.labels = labels;
101+
ans = new int[n];
102+
cnt = new int[26];
103+
dfs(0, -1);
104+
return ans;
105+
}
106+
107+
private void dfs(int i, int fa) {
108+
int k = labels.charAt(i) - 'a';
109+
ans[i] -= cnt[k];
110+
cnt[k]++;
111+
for (int j : g[i]) {
112+
if (j != fa) {
113+
dfs(j, i);
114+
}
115+
}
116+
ans[i] += cnt[k];
117+
}
118+
}
119+
```
120+
121+
### **C++**
122+
123+
```cpp
124+
class Solution {
125+
public:
126+
vector<int> countSubTrees(int n, vector<vector<int>>& edges, string labels) {
127+
vector<vector<int>> g(n);
128+
for (auto& e : edges) {
129+
int a = e[0], b = e[1];
130+
g[a].push_back(b);
131+
g[b].push_back(a);
132+
}
133+
vector<int> ans(n);
134+
int cnt[26]{};
135+
function<void(int, int)> dfs = [&](int i, int fa) {
136+
int k = labels[i] - 'a';
137+
ans[i] -= cnt[k];
138+
cnt[k]++;
139+
for (int& j : g[i]) {
140+
if (j != fa) {
141+
dfs(j, i);
142+
}
143+
}
144+
ans[i] += cnt[k];
145+
};
146+
dfs(0, -1);
147+
return ans;
148+
}
149+
};
150+
```
69151
152+
### **Go**
153+
154+
```go
155+
func countSubTrees(n int, edges [][]int, labels string) []int {
156+
g := make([][]int, n)
157+
for _, e := range edges {
158+
a, b := e[0], e[1]
159+
g[a] = append(g[a], b)
160+
g[b] = append(g[b], a)
161+
}
162+
ans := make([]int, n)
163+
cnt := [26]int{}
164+
var dfs func(int, int)
165+
dfs = func(i, fa int) {
166+
k := labels[i] - 'a'
167+
ans[i] -= cnt[k]
168+
cnt[k]++
169+
for _, j := range g[i] {
170+
if j != fa {
171+
dfs(j, i)
172+
}
173+
}
174+
ans[i] += cnt[k]
175+
}
176+
dfs(0, -1)
177+
return ans
178+
}
70179
```
71180

72181
### **...**
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
class Solution {
2+
public:
3+
vector<int> countSubTrees(int n, vector<vector<int>>& edges, string labels) {
4+
vector<vector<int>> g(n);
5+
for (auto& e : edges) {
6+
int a = e[0], b = e[1];
7+
g[a].push_back(b);
8+
g[b].push_back(a);
9+
}
10+
vector<int> ans(n);
11+
int cnt[26]{};
12+
function<void(int, int)> dfs = [&](int i, int fa) {
13+
int k = labels[i] - 'a';
14+
ans[i] -= cnt[k];
15+
cnt[k]++;
16+
for (int& j : g[i]) {
17+
if (j != fa) {
18+
dfs(j, i);
19+
}
20+
}
21+
ans[i] += cnt[k];
22+
};
23+
dfs(0, -1);
24+
return ans;
25+
}
26+
};
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
func countSubTrees(n int, edges [][]int, labels string) []int {
2+
g := make([][]int, n)
3+
for _, e := range edges {
4+
a, b := e[0], e[1]
5+
g[a] = append(g[a], b)
6+
g[b] = append(g[b], a)
7+
}
8+
ans := make([]int, n)
9+
cnt := [26]int{}
10+
var dfs func(int, int)
11+
dfs = func(i, fa int) {
12+
k := labels[i] - 'a'
13+
ans[i] -= cnt[k]
14+
cnt[k]++
15+
for _, j := range g[i] {
16+
if j != fa {
17+
dfs(j, i)
18+
}
19+
}
20+
ans[i] += cnt[k]
21+
}
22+
dfs(0, -1)
23+
return ans
24+
}

0 commit comments

Comments
 (0)