Skip to content

Navigation Menu

Sign in
Appearance settings

Search code, repositories, users, issues, pull requests...

Provide feedback

We read every piece of feedback, and take your input very seriously.

Saved searches

Use saved searches to filter your results more quickly

Sign up
Appearance settings

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)

AltStyle によって変換されたページ (->オリジナル) /