Skip to content

Commit d8cda5d

Browse files
committed
2158-2204 (2)
1 parent ef605f3 commit d8cda5d

File tree

4 files changed

+233
-0
lines changed

4 files changed

+233
-0
lines changed
Lines changed: 104 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,104 @@
1+
public class Solution2158 {
2+
public int[] amountPainted(int[][] paint) {
3+
int len = paint.length;
4+
5+
DynamicSegTreeUpd dynamicSegTreeUpd = new DynamicSegTreeUpd();
6+
int[] res = new int[len];
7+
for (int i = 0; i < len; i++) {
8+
// 左闭右开
9+
int l = paint[i][0];
10+
int r = paint[i][1] - 1;
11+
res[i] = (r - l + 1) - (int) dynamicSegTreeUpd.getSum(l, r);
12+
dynamicSegTreeUpd.update(l, r, 1);
13+
}
14+
return res;
15+
}
16+
17+
private static class DynamicSegTreeUpd {
18+
private static final int N = Integer.MAX_VALUE;
19+
private final Node root = new Node();
20+
21+
private static class Node {
22+
Node ls, rs;
23+
long sum, lazy;
24+
}
25+
26+
// 区间 [l,r] 置为 val
27+
public void update(int l, int r, int val) {
28+
this.update(l, r, val, 0, N, root);
29+
}
30+
31+
// 区间 [l,r] 求和
32+
public long getSum(int l, int r) {
33+
return this.getSum(l, r, 0, N, root);
34+
}
35+
36+
private void update(int l, int r, int val, int s, int t, Node node) {
37+
if (l <= s && t <= r) {
38+
node.sum = (t - s + 1L) * val;
39+
node.lazy = val;
40+
return;
41+
}
42+
int mid = s + (t - s) / 2;
43+
pushDown(node, s, t, mid);
44+
if (l <= mid) {
45+
update(l, r, val, s, mid, node.ls);
46+
}
47+
if (r > mid) {
48+
update(l, r, val, mid + 1, t, node.rs);
49+
}
50+
pushUp(node);
51+
}
52+
53+
private long getSum(int l, int r, int s, int t, Node node) {
54+
if (l <= s && t <= r) {
55+
return node.sum;
56+
}
57+
int mid = s + (t - s) / 2;
58+
pushDown(node, s, t, mid);
59+
long sum = 0;
60+
if (l <= mid) {
61+
sum = getSum(l, r, s, mid, node.ls);
62+
}
63+
if (r > mid) {
64+
sum += getSum(l, r, mid + 1, t, node.rs);
65+
}
66+
return sum;
67+
}
68+
69+
private void pushDown(Node node, int s, int t, int mid) {
70+
if (node.ls == null) {
71+
node.ls = new Node();
72+
}
73+
if (node.rs == null) {
74+
node.rs = new Node();
75+
}
76+
if (node.lazy > 0) {
77+
node.ls.sum = node.lazy * (mid - s + 1L);
78+
node.rs.sum = node.lazy * (t - mid);
79+
node.ls.lazy = node.lazy;
80+
node.rs.lazy = node.lazy;
81+
node.lazy = 0;
82+
}
83+
}
84+
85+
private void pushUp(Node node) {
86+
node.sum = node.ls.sum + node.rs.sum;
87+
}
88+
}
89+
}
90+
/*
91+
$2158. 每天绘制新区域的数量
92+
https://leetcode.cn/problems/amount-of-new-area-painted-each-day/
93+
94+
有一幅细长的画,可以用数轴来表示。 给你一个长度为 n 、下标从 0 开始的二维整数数组 paint ,其中 paint[i] = [starti, endi] 表示在第 i 天你需要绘制 starti 和 endi 之间的区域。
95+
多次绘制同一区域会导致不均匀,因此每个区域最多只能绘制 一次 。
96+
返回一个长度为 n 的整数数组 worklog,其中 worklog[i] 是你在第 i 天绘制的 新 区域的数量。
97+
提示:
98+
1 <= paint.length <= 10^5
99+
paint[i].length == 2
100+
0 <= starti < endi <= 5 * 10^4
101+
102+
线段树
103+
区间并查集 https://leetcode.cn/problems/amount-of-new-area-painted-each-day/solution/qu-jian-bing-cha-ji-by-981377660lmt-p1zl/
104+
*/
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution2158Tests {
5+
private final Solution2158 solution2158 = new Solution2158();
6+
7+
@Test
8+
public void example1() {
9+
int[][] paint = UtUtils.stringToInts2("[[1,4],[4,7],[5,8]]");
10+
int[] expected = {3, 3, 1};
11+
Assertions.assertArrayEquals(expected, solution2158.amountPainted(paint));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[][] paint = UtUtils.stringToInts2("[[1,4],[5,8],[4,7]]");
17+
int[] expected = {3, 3, 1};
18+
Assertions.assertArrayEquals(expected, solution2158.amountPainted(paint));
19+
}
20+
21+
@Test
22+
public void example3() {
23+
int[][] paint = UtUtils.stringToInts2("[[1,5],[2,4]]");
24+
int[] expected = {4, 0};
25+
Assertions.assertArrayEquals(expected, solution2158.amountPainted(paint));
26+
}
27+
}
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import java.util.ArrayList;
2+
import java.util.HashMap;
3+
import java.util.LinkedList;
4+
import java.util.List;
5+
import java.util.Map;
6+
import java.util.Queue;
7+
8+
public class Solution2204 {
9+
private Map<Integer, List<Integer>> g;
10+
private int[] deg;
11+
private int[] ans;
12+
13+
public int[] distanceToCycle(int n, int[][] edges) {
14+
g = new HashMap<>();
15+
deg = new int[n];
16+
for (int[] edge : edges) {
17+
int u = edge[0];
18+
int v = edge[1];
19+
g.computeIfAbsent(u, key -> new ArrayList<>()).add(v);
20+
g.computeIfAbsent(v, key -> new ArrayList<>()).add(u);
21+
deg[u]++;
22+
deg[v]++;
23+
}
24+
25+
// 拓扑排序,剪掉所有树枝
26+
Queue<Integer> queue = new LinkedList<>();
27+
for (int i = 0; i < n; i++) {
28+
if (deg[i] == 1) {
29+
queue.add(i);
30+
}
31+
}
32+
while (!queue.isEmpty()) {
33+
int u = queue.remove();
34+
for (int v : g.getOrDefault(u, new ArrayList<>())) {
35+
deg[v]--;
36+
if (deg[v] == 1) {
37+
queue.add(v);
38+
}
39+
}
40+
}
41+
42+
// 从基环出发,求所有树枝上的点的深度
43+
ans = new int[n];
44+
for (int root = 0; root < n; root++) {
45+
if (deg[root] > 1) {
46+
f(root, -1);
47+
}
48+
}
49+
return ans;
50+
}
51+
52+
private void f(int u, int fa) {
53+
for (int v : g.getOrDefault(u, new ArrayList<>())) {
54+
if (v != fa && deg[v] < 2) {
55+
ans[v] = ans[u] + 1;
56+
f(v, u);
57+
}
58+
}
59+
}
60+
}
61+
/*
62+
$2204. 无向图中到环的距离
63+
https://leetcode.cn/problems/distance-to-a-cycle-in-undirected-graph/
64+
65+
给定一个正整数 n,表示一个 连通无向图 中的节点数,该图 只包含一个 环。节点编号为 0 ~ n - 1(含)。
66+
你还得到了一个二维整数数组 edges,其中 edges[i] = [node1i, node2i] 表示有一条 双向 边连接图中的 node1i 和 node2i。
67+
两个节点 a 和 b 之间的距离定义为从 a 到 b 所需的 最小边数。
68+
返回一个长度为 n 的整数数组 answer,其中 answer[i] 是第 i 个节点与环中任何节点之间的最小距离。
69+
提示:
70+
3 <= n <= 10^5
71+
edges.length == n
72+
edges[i].length == 2
73+
0 <= node1i, node2i <= n - 1
74+
node1i != node2i
75+
图是连通的。
76+
这个图只有一个环。
77+
任何顶点对之间最多只有一条边。
78+
79+
无向基环树 https://leetcode.cn/problems/distance-to-a-cycle-in-undirected-graph/solution/by-endlesscheng-422f/
80+
*/
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution2204Tests {
5+
private final Solution2204 solution2204 = new Solution2204();
6+
7+
@Test
8+
public void example1() {
9+
int n = 7;
10+
int[][] edges = UtUtils.stringToInts2("[[1,2],[2,4],[4,3],[3,1],[0,1],[5,2],[6,5]]");
11+
int[] expected = {1, 0, 0, 0, 0, 1, 2};
12+
Assertions.assertArrayEquals(expected, solution2204.distanceToCycle(n, edges));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
int n = 9;
18+
int[][] edges = UtUtils.stringToInts2("[[0,1],[1,2],[0,2],[2,6],[6,7],[6,8],[0,3],[3,4],[3,5]]");
19+
int[] expected = {0, 0, 0, 1, 2, 2, 1, 2, 2};
20+
Assertions.assertArrayEquals(expected, solution2204.distanceToCycle(n, edges));
21+
}
22+
}

0 commit comments

Comments
 (0)