Skip to content

Commit c80336c

Browse files
committed
feat: add solutions to lc problem: No.1857
No.1857.Largest Color Value in a Directed Graph
1 parent e188f51 commit c80336c

File tree

3 files changed

+144
-3
lines changed

3 files changed

+144
-3
lines changed

solution/1800-1899/1857.Largest Color Value in a Directed Graph/README.md

Lines changed: 52 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -72,9 +72,17 @@ tags:
7272

7373
### 方法一:拓扑排序 + 动态规划
7474

75-
求出每个点的入度,进行拓扑排序。每个点维护一个长度为 $26$ 的数组,记录每个字母从任意起点到当前点的出现次数。
75+
求出每个点的入度,进行拓扑排序。
7676

77-
时间复杂度 $O(n+m)$,空间复杂度 $O(n+m)$。
77+
定义一个二维数组 $dp$,其中 $dp[i][j]$ 表示从起点到 $i$ 点,颜色为 $j$ 的节点数目。
78+
79+
从 $i$ 点出发,遍历所有出边 $i \to j$,更新 $dp[j][k] = \max(dp[j][k], dp[i][k] + (c == k))$,其中 $c$ 是 $j$ 点的颜色。
80+
81+
答案为数组 $dp$ 中的最大值。
82+
83+
如果图中有环,则无法遍历完所有点,返回 $-1$。
84+
85+
时间复杂度 $O((n + m) \times |\Sigma|)$,空间复杂度 $O(m + n \times |\Sigma)$。其中 $|\Sigma|$ 是字母表大小,这里为 $26$,而且 $n$ 和 $m$ 分别是节点数和边数。
7886

7987
<!-- tabs:start -->
8088

@@ -252,6 +260,48 @@ func largestPathValue(colors string, edges [][]int) int {
252260
}
253261
```
254262

263+
#### TypeScript
264+
265+
```ts
266+
function largestPathValue(colors: string, edges: number[][]): number {
267+
const n = colors.length;
268+
const indeg = Array(n).fill(0);
269+
const g: Map<number, number[]> = new Map();
270+
for (const [a, b] of edges) {
271+
if (!g.has(a)) g.set(a, []);
272+
g.get(a)!.push(b);
273+
indeg[b]++;
274+
}
275+
const q: number[] = [];
276+
const dp: number[][] = Array.from({ length: n }, () => Array(26).fill(0));
277+
for (let i = 0; i < n; i++) {
278+
if (indeg[i] === 0) {
279+
q.push(i);
280+
const c = colors.charCodeAt(i) - 97;
281+
dp[i][c]++;
282+
}
283+
}
284+
let cnt = 0;
285+
let ans = 1;
286+
while (q.length) {
287+
const i = q.pop()!;
288+
cnt++;
289+
if (g.has(i)) {
290+
for (const j of g.get(i)!) {
291+
indeg[j]--;
292+
if (indeg[j] === 0) q.push(j);
293+
const c = colors.charCodeAt(j) - 97;
294+
for (let k = 0; k < 26; k++) {
295+
dp[j][k] = Math.max(dp[j][k], dp[i][k] + (c === k ? 1 : 0));
296+
ans = Math.max(ans, dp[j][k]);
297+
}
298+
}
299+
}
300+
}
301+
return cnt < n ? -1 : ans;
302+
}
303+
```
304+
255305
<!-- tabs:end -->
256306

257307
<!-- solution:end -->

solution/1800-1899/1857.Largest Color Value in a Directed Graph/README_EN.md

Lines changed: 55 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,19 @@ tags:
8787

8888
<!-- solution:start -->
8989

90-
### Solution 1
90+
### Solution 1: Topological Sort + Dynamic Programming
91+
92+
Calculate the in-degree of each node and perform a topological sort.
93+
94+
Define a 2D array $dp$, where $dp[i][j]$ represents the number of nodes with color $j$ on the path from the start node to node $i$.
95+
96+
From node $i$, traverse all outgoing edges $i \to j$, and update $dp[j][k] = \max(dp[j][k], dp[i][k] + (c == k))$, where $c$ is the color of node $j$.
97+
98+
The answer is the maximum value in the $dp$ array.
99+
100+
If there is a cycle in the graph, it is impossible to visit all nodes, so return $-1$.
101+
102+
The time complexity is $O((n + m) \times |\Sigma|)$, and the space complexity is $O(m + n \times |\Sigma|)$. Here, $|\Sigma|$ is the size of the alphabet (26 in this case), and $n$ and $m$ are the number of nodes and edges, respectively.
91103

92104
<!-- tabs:start -->
93105

@@ -265,6 +277,48 @@ func largestPathValue(colors string, edges [][]int) int {
265277
}
266278
```
267279

280+
#### TypeScript
281+
282+
```ts
283+
function largestPathValue(colors: string, edges: number[][]): number {
284+
const n = colors.length;
285+
const indeg = Array(n).fill(0);
286+
const g: Map<number, number[]> = new Map();
287+
for (const [a, b] of edges) {
288+
if (!g.has(a)) g.set(a, []);
289+
g.get(a)!.push(b);
290+
indeg[b]++;
291+
}
292+
const q: number[] = [];
293+
const dp: number[][] = Array.from({ length: n }, () => Array(26).fill(0));
294+
for (let i = 0; i < n; i++) {
295+
if (indeg[i] === 0) {
296+
q.push(i);
297+
const c = colors.charCodeAt(i) - 97;
298+
dp[i][c]++;
299+
}
300+
}
301+
let cnt = 0;
302+
let ans = 1;
303+
while (q.length) {
304+
const i = q.pop()!;
305+
cnt++;
306+
if (g.has(i)) {
307+
for (const j of g.get(i)!) {
308+
indeg[j]--;
309+
if (indeg[j] === 0) q.push(j);
310+
const c = colors.charCodeAt(j) - 97;
311+
for (let k = 0; k < 26; k++) {
312+
dp[j][k] = Math.max(dp[j][k], dp[i][k] + (c === k ? 1 : 0));
313+
ans = Math.max(ans, dp[j][k]);
314+
}
315+
}
316+
}
317+
}
318+
return cnt < n ? -1 : ans;
319+
}
320+
```
321+
268322
<!-- tabs:end -->
269323

270324
<!-- solution:end -->
Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
function largestPathValue(colors: string, edges: number[][]): number {
2+
const n = colors.length;
3+
const indeg = Array(n).fill(0);
4+
const g: Map<number, number[]> = new Map();
5+
for (const [a, b] of edges) {
6+
if (!g.has(a)) g.set(a, []);
7+
g.get(a)!.push(b);
8+
indeg[b]++;
9+
}
10+
const q: number[] = [];
11+
const dp: number[][] = Array.from({ length: n }, () => Array(26).fill(0));
12+
for (let i = 0; i < n; i++) {
13+
if (indeg[i] === 0) {
14+
q.push(i);
15+
const c = colors.charCodeAt(i) - 97;
16+
dp[i][c]++;
17+
}
18+
}
19+
let cnt = 0;
20+
let ans = 1;
21+
while (q.length) {
22+
const i = q.pop()!;
23+
cnt++;
24+
if (g.has(i)) {
25+
for (const j of g.get(i)!) {
26+
indeg[j]--;
27+
if (indeg[j] === 0) q.push(j);
28+
const c = colors.charCodeAt(j) - 97;
29+
for (let k = 0; k < 26; k++) {
30+
dp[j][k] = Math.max(dp[j][k], dp[i][k] + (c === k ? 1 : 0));
31+
ans = Math.max(ans, dp[j][k]);
32+
}
33+
}
34+
}
35+
}
36+
return cnt < n ? -1 : ans;
37+
}

0 commit comments

Comments
 (0)