Skip to content

Commit bbb90b2

Browse files
committed
第160场双周赛T1~T4 & 第457场周赛T1~T4 (8)
1 parent 1b7c52a commit bbb90b2

19 files changed

+944
-0
lines changed

jacoco-aggregate-report/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -336,6 +336,11 @@
336336
<artifactId>leetcode-36</artifactId>
337337
<version>1.0-SNAPSHOT</version>
338338
</dependency>
339+
<dependency>
340+
<groupId>com.devyy</groupId>
341+
<artifactId>leetcode-37</artifactId>
342+
<version>1.0-SNAPSHOT</version>
343+
</dependency>
339344

340345

341346
<dependency>

leetcode/leetcode-37/pom.xml

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<project xmlns="http://maven.apache.org/POM/4.0.0"
3+
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
4+
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
5+
<modelVersion>4.0.0</modelVersion>
6+
<parent>
7+
<groupId>com.devyy</groupId>
8+
<artifactId>leetcode</artifactId>
9+
<version>1.0-SNAPSHOT</version>
10+
</parent>
11+
12+
<artifactId>leetcode-37</artifactId>
13+
14+
<properties>
15+
<maven.compiler.source>21</maven.compiler.source>
16+
<maven.compiler.target>21</maven.compiler.target>
17+
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
18+
</properties>
19+
20+
<dependencies>
21+
<dependency>
22+
<groupId>com.devyy</groupId>
23+
<artifactId>leetcode-core</artifactId>
24+
<version>1.0-SNAPSHOT</version>
25+
</dependency>
26+
</dependencies>
27+
</project>
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
public class Solution3602 {
2+
public String concatHex36(int n) {
3+
String n2 = Integer.toString(n * n, 16);
4+
String n3 = Integer.toString(n * n * n, 36);
5+
return (n2 + n3).toUpperCase();
6+
}
7+
}
8+
/*
9+
3602. 十六进制和三十六进制转化
10+
https://leetcode.cn/problems/hexadecimal-and-hexatrigesimal-conversion/description/
11+
12+
第 160 场双周赛 T1。
13+
14+
给你一个整数 n。
15+
返回 n^2 的 十六进制表示 和 n^3 的 三十六进制表示 拼接成的字符串。
16+
十六进制 数定义为使用数字 0 – 9 和大写字母 A - F 表示 0 到 15 的值。
17+
三十六进制 数定义为使用数字 0 – 9 和大写字母 A - Z 表示 0 到 35 的值。
18+
提示:
19+
1 <= n <= 1000
20+
21+
库函数。
22+
时间复杂度 O(logn)。
23+
*/
Lines changed: 57 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,57 @@
1+
public class Solution3603 {
2+
public long minCost(int m, int n, int[][] waitCost) {
3+
long[][] grid = new long[m][n];
4+
for (int i = 0; i < m; i++) {
5+
for (int j = 0; j < n; j++) {
6+
if (i == 0 && j == 0) {
7+
grid[i][j] = 1;
8+
} else if (i == m - 1 && j == n - 1) {
9+
grid[i][j] = (long) (i + 1) * (j + 1);
10+
} else {
11+
grid[i][j] = (long) (i + 1) * (j + 1) + waitCost[i][j];
12+
}
13+
}
14+
}
15+
16+
long[][] f = new long[m][n];
17+
f[0][0] = grid[0][0];
18+
for (int i = 1; i < m; i++) {
19+
f[i][0] = f[i - 1][0] + grid[i][0];
20+
}
21+
for (int j = 1; j < n; j++) {
22+
f[0][j] = f[0][j - 1] + grid[0][j];
23+
}
24+
for (int i = 1; i < m; i++) {
25+
for (int j = 1; j < n; j++) {
26+
f[i][j] = Math.min(f[i - 1][j], f[i][j - 1]) + grid[i][j];
27+
}
28+
}
29+
return f[m - 1][n - 1];
30+
}
31+
}
32+
/*
33+
3603. 交替方向的最小路径代价 II
34+
https://leetcode.cn/problems/minimum-cost-path-with-alternating-directions-ii/description/
35+
36+
第 160 场双周赛 T2。
37+
38+
给你两个整数 m 和 n,分别表示网格的行数和列数。
39+
进入单元格 (i, j) 的成本定义为 (i + 1) * (j + 1)。
40+
另外给你一个二维整数数组 waitCost,其中 waitCost[i][j] 定义了在该单元格 等待 的成本。
41+
你从第 1 秒开始在单元格 (0, 0)。
42+
每一步,你都遵循交替模式:
43+
- 在 奇数秒 ,你必须向 右 或向 下 移动到 相邻 的单元格,并支付其进入成本。
44+
- 在 偶数秒 ,你必须原地 等待 ,并支付 waitCost[i][j]。
45+
返回到达 (m - 1, n - 1) 所需的 最小 总成本。
46+
提示:
47+
1 <= m, n <= 10^5
48+
2 <= m * n <= 10^5
49+
waitCost.length == m
50+
waitCost[0].length == n
51+
0 <= waitCost[i][j] <= 10^5
52+
53+
动态规划。
54+
时间复杂度 O(mn)。
55+
相似题目: 64. 最小路径和
56+
https://leetcode.cn/problems/minimum-path-sum/
57+
*/
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.Comparator;
4+
import java.util.List;
5+
import java.util.PriorityQueue;
6+
7+
public class Solution3604 {
8+
public int minTime(int n, int[][] edges) {
9+
if (n == 1) {
10+
return 0;
11+
}
12+
List<int[]>[] g = new ArrayList[n];
13+
Arrays.setAll(g, e -> new ArrayList<>());
14+
for (int[] p : edges) {
15+
int u = p[0], v = p[1], s = p[2], e = p[3];
16+
g[u].add(new int[]{v, s, e});
17+
}
18+
19+
int[] dist = new int[n];
20+
Arrays.fill(dist, Integer.MAX_VALUE);
21+
dist[0] = 0;
22+
PriorityQueue<int[]> pq = new PriorityQueue<>(Comparator.comparingInt(a -> a[0]));
23+
pq.add(new int[]{0, 0});
24+
25+
while (!pq.isEmpty()) {
26+
int[] cur = pq.remove();
27+
int cur_time = cur[0], u = cur[1];
28+
if (u == n - 1) {
29+
return cur_time;
30+
}
31+
if (cur_time > dist[u]) {
32+
continue;
33+
}
34+
for (int[] p : g[u]) {
35+
int v = p[0], s = p[1], e = p[2];
36+
if (cur_time > e) {
37+
continue;
38+
}
39+
int new_time = Math.max(cur_time, s) + 1;
40+
if (dist[v] > new_time) {
41+
dist[v] = new_time;
42+
pq.add(new int[]{new_time, v});
43+
}
44+
}
45+
}
46+
return dist[n - 1] == Integer.MAX_VALUE ? -1 : dist[n - 1];
47+
}
48+
}
49+
/*
50+
3604. 有向图中到达终点的最少时间
51+
https://leetcode.cn/problems/minimum-time-to-reach-destination-in-directed-graph/description/
52+
53+
第 160 场双周赛 T3。
54+
55+
给你一个整数 n 和一个 有向 图,图中有 n 个节点,编号从 0 到 n - 1。图由一个二维数组 edges 表示,其中 edges[i] = [ui, vi, starti, endi] 表示从节点 ui 到 vi 的一条边,该边 只能 在满足 starti <= t <= endi 的整数时间 t 使用。
56+
你在时间 0 从在节点 0 出发。
57+
在一个时间单位内,你可以:
58+
- 停留在当前节点不动,或者
59+
- 如果当前时间 t 满足 starti <= t <= endi,则从当前节点沿着出边的方向移动。
60+
返回到达节点 n - 1 所需的 最小 时间。如果不可能,返回 -1。
61+
提示:
62+
1 <= n <= 10^5
63+
0 <= edges.length <= 10^5
64+
edges[i] == [ui, vi, starti, endi]
65+
0 <= ui, vi <= n - 1
66+
ui != vi
67+
0 <= starti <= endi <= 10^9
68+
69+
Dijkstra 求最短路。
70+
时间复杂度 O(n + mlogm)。
71+
*/
Lines changed: 185 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,185 @@
1+
import java.util.ArrayList;
2+
import java.util.Comparator;
3+
import java.util.List;
4+
5+
public class Solution3605 {
6+
// 200ms
7+
static class V1 {
8+
private int[][] st;
9+
private int[] log;
10+
private int n;
11+
12+
public int minStable(int[] nums, int maxC) {
13+
n = nums.length;
14+
if (n == 0) return 0;
15+
buildSparseTable(nums);
16+
precomputeLogs();
17+
18+
int low = 0, high = n;
19+
while (low <= high) {
20+
int mid = (low + high) >> 1;
21+
if (check(mid, maxC, nums)) {
22+
high = mid - 1;
23+
} else {
24+
low = mid + 1;
25+
}
26+
}
27+
return low;
28+
}
29+
30+
private boolean check(int k, int maxC, int[] nums) {
31+
if (k == 0) {
32+
int count = 0;
33+
for (int num : nums) {
34+
if (num >= 2) count++;
35+
}
36+
return count <= maxC;
37+
}
38+
int L = k + 1;
39+
if (L > n) {
40+
return true;
41+
}
42+
List<int[]> intervals = new ArrayList<>();
43+
for (int i = 0; i <= n - L; i++) {
44+
int g = queryGCD(i, i + L - 1);
45+
if (g >= 2) {
46+
intervals.add(new int[]{i, i + L - 1});
47+
}
48+
}
49+
if (intervals.isEmpty()) {
50+
return true;
51+
}
52+
intervals.sort(Comparator.comparingInt(a -> a[1]));
53+
int points = 0;
54+
int last = -1;
55+
for (int[] interval : intervals) {
56+
int left = interval[0];
57+
int right = interval[1];
58+
if (left > last) {
59+
points++;
60+
last = right;
61+
}
62+
}
63+
return points <= maxC;
64+
}
65+
66+
private void buildSparseTable(int[] nums) {
67+
int k = (int) (Math.log(n) / Math.log(2)) + 1;
68+
st = new int[k][n];
69+
System.arraycopy(nums, 0, st[0], 0, n);
70+
for (int j = 1; j < k; j++) {
71+
int step = 1 << (j - 1);
72+
for (int i = 0; i + (1 << j) <= n; i++) {
73+
st[j][i] = gcd(st[j - 1][i], st[j - 1][i + step]);
74+
}
75+
}
76+
}
77+
78+
private void precomputeLogs() {
79+
log = new int[n + 1];
80+
log[1] = 0;
81+
for (int i = 2; i <= n; i++) {
82+
log[i] = log[i / 2] + 1;
83+
}
84+
}
85+
86+
private int queryGCD(int l, int r) {
87+
int len = r - l + 1;
88+
int j = log[len];
89+
return gcd(st[j][l], st[j][r - (1 << j) + 1]);
90+
}
91+
92+
private int gcd(int a, int b) {
93+
if (b == 0) return a;
94+
return gcd(b, a % b);
95+
}
96+
}
97+
98+
// 144ms
99+
static class V2 {
100+
public int minStable(int[] nums, int maxC) {
101+
int left = 0;
102+
int right = nums.length / (maxC + 1);
103+
while (left < right) {
104+
int mid = left + (right - left) / 2;
105+
// 边界二分 F, F,..., F, [T, T,..., T]
106+
// ----------------------^
107+
if (check(nums, maxC, mid)) {
108+
right = mid;
109+
} else {
110+
left = mid + 1;
111+
}
112+
}
113+
return left;
114+
}
115+
116+
private boolean check(int[] nums, int maxC, int upper) {
117+
List<int[]> intervals = new ArrayList<>(); // 每个元素是 (子数组 GCD,最小左端点)
118+
for (int i = 0; i < nums.length; i++) {
119+
int x = nums[i];
120+
121+
// 计算以 i 为右端点的子数组 GCD
122+
for (int[] interval : intervals) {
123+
interval[0] = getGCD(interval[0], x);
124+
}
125+
// nums[i] 单独一个数作为子数组
126+
intervals.add(new int[]{x, i});
127+
128+
// 去重(合并 GCD 相同的区间)
129+
int idx = 1;
130+
for (int j = 1; j < intervals.size(); j++) {
131+
if (intervals.get(j)[0] != intervals.get(j - 1)[0]) {
132+
intervals.set(idx, intervals.get(j));
133+
idx++;
134+
}
135+
}
136+
intervals.subList(idx, intervals.size()).clear();
137+
138+
// intervals 的性质:越靠左,GCD 越小
139+
140+
// 我们只关心 GCD >= 2 的子数组
141+
if (intervals.get(0)[0] == 1) {
142+
intervals.remove(0);
143+
}
144+
145+
// intervals[0] 的 GCD >= 2 且最长,取其区间左端点作为子数组的最小左端点
146+
if (!intervals.isEmpty() && i - intervals.get(0)[1] + 1 > upper) {
147+
if (maxC == 0) {
148+
return false;
149+
}
150+
maxC--;
151+
intervals.clear(); // 修改后 GCD 均为 1,直接清空
152+
}
153+
}
154+
return true;
155+
}
156+
157+
private int getGCD(int num1, int num2) {
158+
return num1 == 0 ? num2 : getGCD(num2 % num1, num1);
159+
}
160+
}
161+
}
162+
/*
163+
3605. 数组的最小稳定性因子
164+
https://leetcode.cn/problems/minimum-stability-factor-of-array/description/
165+
166+
第 160 场双周赛 T4。
167+
168+
给你一个整数数组 nums 和一个整数 maxC。
169+
如果一个 子数组 的所有元素的最大公因数(简称 HCF) 大于或等于 2,则称该子数组是稳定的。
170+
一个数组的 稳定性因子 定义为其 最长 稳定子数组的长度。
171+
你 最多 可以修改数组中的 maxC 个元素为任意整数。
172+
在最多 maxC 次修改后,返回数组的 最小 可能稳定性因子。如果没有稳定的子数组,则返回 0。
173+
注意:
174+
- 子数组 是数组中连续的元素序列。
175+
- 数组的 最大公因数(HCF)是能同时整除数组中所有元素的最大整数。
176+
- 如果长度为 1 的 子数组 中唯一元素大于等于 2,那么它是稳定的,因为 HCF([x]) = x。
177+
提示:
178+
1 <= n == nums.length <= 10^5
179+
1 <= nums[i] <= 10^9
180+
0 <= maxC <= n
181+
182+
二分答案 + ST 表。
183+
时间复杂度 O(nlogU)
184+
二分答案 + logTrick。
185+
*/

0 commit comments

Comments
 (0)