Skip to content

Commit 5734932

Browse files
committed
feat: add solution 3373. Maximize the Number of Target Nodes After Connecting Trees II
1 parent 94557d5 commit 5734932

File tree

2 files changed

+194
-0
lines changed

2 files changed

+194
-0
lines changed
Lines changed: 135 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,135 @@
1+
# [3373. Maximize the Number of Target Nodes After Connecting Trees II](https://leetcode.com/problems/maximize-the-number-of-target-nodes-after-connecting-trees-ii)
2+
3+
## Description
4+
5+
<div class="elfjS" data-track-load="description_content"><p>There exist two <strong>undirected </strong>trees with <code>n</code> and <code>m</code> nodes, labeled from <code>[0, n - 1]</code> and <code>[0, m - 1]</code>, respectively.</p>
6+
7+
<p>You are given two 2D integer arrays <code>edges1</code> and <code>edges2</code> of lengths <code>n - 1</code> and <code>m - 1</code>, respectively, where <code>edges1[i] = [a<sub>i</sub>, b<sub>i</sub>]</code> indicates that there is an edge between nodes <code>a<sub>i</sub></code> and <code>b<sub>i</sub></code> in the first tree and <code>edges2[i] = [u<sub>i</sub>, v<sub>i</sub>]</code> indicates that there is an edge between nodes <code>u<sub>i</sub></code> and <code>v<sub>i</sub></code> in the second tree.</p>
8+
9+
<p>Node <code>u</code> is <strong>target</strong> to node <code>v</code> if the number of edges on the path from <code>u</code> to <code>v</code> is even.&nbsp;<strong>Note</strong> that a node is <em>always</em> <strong>target</strong> to itself.</p>
10+
11+
<p>Return an array of <code>n</code> integers <code>answer</code>, where <code>answer[i]</code> is the <strong>maximum</strong> possible number of nodes that are <strong>target</strong> to node <code>i</code> of the first tree if you had to connect one node from the first tree to another node in the second tree.</p>
12+
13+
<p><strong>Note</strong> that queries are independent from each other. That is, for every query you will remove the added edge before proceeding to the next query.</p>
14+
15+
<p>&nbsp;</p>
16+
<p><strong class="example">Example 1:</strong></p>
17+
18+
<div class="example-block">
19+
<p><strong>Input:</strong> <span class="example-io">edges1 = [[0,1],[0,2],[2,3],[2,4]], edges2 = [[0,1],[0,2],[0,3],[2,7],[1,4],[4,5],[4,6]]</span></p>
20+
21+
<p><strong>Output:</strong> <span class="example-io">[8,7,7,8,8]</span></p>
22+
23+
<p><strong>Explanation:</strong></p>
24+
25+
<ul>
26+
<li>For <code>i = 0</code>, connect node 0 from the first tree to node 0 from the second tree.</li>
27+
<li>For <code>i = 1</code>, connect node 1 from the first tree to node 4 from the second tree.</li>
28+
<li>For <code>i = 2</code>, connect node 2 from the first tree to node 7 from the second tree.</li>
29+
<li>For <code>i = 3</code>, connect node 3 from the first tree to node 0 from the second tree.</li>
30+
<li>For <code>i = 4</code>, connect node 4 from the first tree to node 4 from the second tree.</li>
31+
</ul>
32+
<img alt="" src="https://assets.leetcode.com/uploads/2024/09/24/3982-1.png" style="width: 600px; height: 169px;"></div>
33+
34+
<p><strong class="example">Example 2:</strong></p>
35+
36+
<div class="example-block">
37+
<p><strong>Input:</strong> <span class="example-io">edges1 = [[0,1],[0,2],[0,3],[0,4]], edges2 = [[0,1],[1,2],[2,3]]</span></p>
38+
39+
<p><strong>Output:</strong> <span class="example-io">[3,6,6,6,6]</span></p>
40+
41+
<p><strong>Explanation:</strong></p>
42+
43+
<p>For every <code>i</code>, connect node <code>i</code> of the first tree with any node of the second tree.</p>
44+
<img alt="" src="https://assets.leetcode.com/uploads/2024/09/24/3928-2.png" style="height: 281px; width: 500px;"></div>
45+
46+
<p>&nbsp;</p>
47+
<p><strong>Constraints:</strong></p>
48+
49+
<ul>
50+
<li><code>2 &lt;= n, m &lt;= 10<sup>5</sup></code></li>
51+
<li><code>edges1.length == n - 1</code></li>
52+
<li><code>edges2.length == m - 1</code></li>
53+
<li><code>edges1[i].length == edges2[i].length == 2</code></li>
54+
<li><code>edges1[i] = [a<sub>i</sub>, b<sub>i</sub>]</code></li>
55+
<li><code>0 &lt;= a<sub>i</sub>, b<sub>i</sub> &lt; n</code></li>
56+
<li><code>edges2[i] = [u<sub>i</sub>, v<sub>i</sub>]</code></li>
57+
<li><code>0 &lt;= u<sub>i</sub>, v<sub>i</sub> &lt; m</code></li>
58+
<li>The input is generated such that <code>edges1</code> and <code>edges2</code> represent valid trees.</li>
59+
</ul>
60+
</div>
61+
62+
<p>&nbsp;</p>
63+
64+
## Solutions
65+
66+
**Solution: `Depth-First Search`**
67+
68+
- Time complexity: <em>O(m+n)</em>
69+
- Space complexity: <em>O(m+n)</em>
70+
71+
<p>&nbsp;</p>
72+
73+
### **JavaScript**
74+
75+
```js
76+
/**
77+
* @param {number[][]} edges1
78+
* @param {number[][]} edges2
79+
* @return {number[]}
80+
*/
81+
const maxTargetNodes = function (edges1, edges2) {
82+
const createTree = (edge, n) => {
83+
const tree = Array.from({ length: n }, () => []);
84+
85+
for (const [a, b] of edge) {
86+
tree[a].push(b);
87+
tree[b].push(a);
88+
}
89+
90+
return tree;
91+
};
92+
93+
const m = edges1.length + 1;
94+
const n = edges2.length + 1;
95+
const tree1 = createTree(edges1, m);
96+
const tree2 = createTree(edges2, n);
97+
98+
const getNodeCount = (tree, isEven) => {
99+
const count = Array.from({ length: 2 }, () => 0);
100+
101+
const dfsTree = (node, prev, index) => {
102+
count[index] += 1;
103+
104+
for (const neighbor of tree[node]) {
105+
if (prev === neighbor) continue;
106+
107+
dfsTree(neighbor, node, index ^ 1);
108+
}
109+
};
110+
111+
dfsTree(0, -1, isEven ? 1 : 0);
112+
113+
return count;
114+
};
115+
116+
const count1 = getNodeCount(tree1, true);
117+
const count2 = getNodeCount(tree2, false);
118+
const maxPathCount = Math.max(...count2);
119+
const path = Array.from({ length: m }, () => false);
120+
121+
const setNodePath = (node, prev, isEven) => {
122+
path[node] = isEven;
123+
124+
for (const neighbor of tree1[node]) {
125+
if (prev === neighbor) continue;
126+
127+
setNodePath(neighbor, node, !isEven);
128+
}
129+
};
130+
131+
setNodePath(0, -1, true);
132+
133+
return path.map(isEven => maxPathCount + count1[isEven ? 1 : 0]);
134+
};
135+
```
Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
/**
2+
* @param {number[][]} edges1
3+
* @param {number[][]} edges2
4+
* @return {number[]}
5+
*/
6+
const maxTargetNodes = function (edges1, edges2) {
7+
const createTree = (edge, n) => {
8+
const tree = Array.from({ length: n }, () => []);
9+
10+
for (const [a, b] of edge) {
11+
tree[a].push(b);
12+
tree[b].push(a);
13+
}
14+
15+
return tree;
16+
};
17+
18+
const m = edges1.length + 1;
19+
const n = edges2.length + 1;
20+
const tree1 = createTree(edges1, m);
21+
const tree2 = createTree(edges2, n);
22+
23+
const getNodeCount = (tree, isEven) => {
24+
const count = Array.from({ length: 2 }, () => 0);
25+
26+
const dfsTree = (node, prev, index) => {
27+
count[index] += 1;
28+
29+
for (const neighbor of tree[node]) {
30+
if (prev === neighbor) continue;
31+
32+
dfsTree(neighbor, node, index ^ 1);
33+
}
34+
};
35+
36+
dfsTree(0, -1, isEven ? 1 : 0);
37+
38+
return count;
39+
};
40+
41+
const count1 = getNodeCount(tree1, true);
42+
const count2 = getNodeCount(tree2, false);
43+
const maxPathCount = Math.max(...count2);
44+
const path = Array.from({ length: m }, () => false);
45+
46+
const setNodePath = (node, prev, isEven) => {
47+
path[node] = isEven;
48+
49+
for (const neighbor of tree1[node]) {
50+
if (prev === neighbor) continue;
51+
52+
setNodePath(neighbor, node, !isEven);
53+
}
54+
};
55+
56+
setNodePath(0, -1, true);
57+
58+
return path.map(isEven => maxPathCount + count1[isEven ? 1 : 0]);
59+
};

0 commit comments

Comments
 (0)