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 ae907ec

Browse files
committed
第155场双周赛T1~T4 & 第447场周赛T1~T4 (8)
1 parent 7d69b5c commit ae907ec

16 files changed

+731
-0
lines changed
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
import java.util.HashMap;
2+
import java.util.List;
3+
import java.util.Map;
4+
5+
public class Solution3527 {
6+
public String findCommonResponse(List<List<String>> responses) {
7+
Map<String, Integer> cnt = new HashMap<>();
8+
responses.forEach(list -> list.stream().distinct().forEach(v -> cnt.merge(v, 1, Integer::sum)));
9+
10+
String ans = "";
11+
int maxCnt = 0;
12+
for (Map.Entry<String, Integer> entry : cnt.entrySet()) {
13+
if (entry.getValue() > maxCnt) {
14+
maxCnt = entry.getValue();
15+
ans = entry.getKey();
16+
} else if (entry.getValue() == maxCnt && ans.compareTo(entry.getKey()) > 0) {
17+
ans = entry.getKey();
18+
}
19+
}
20+
return ans;
21+
}
22+
}
23+
/*
24+
3527. 找到最常见的回答
25+
https://leetcode.cn/problems/find-the-most-common-response/description/
26+
27+
第 155 场双周赛 T1。
28+
29+
给你一个二维字符串数组 responses,其中每个 responses[i] 是一个字符串数组,表示第 i 天调查的回答结果。
30+
请返回在对每个 responses[i] 中的回答 去重 后,所有天数中 最常见 的回答。如果有多个回答出现频率相同,则返回 字典序最小 的那个回答。
31+
提示:
32+
1 <= responses.length <= 1000
33+
1 <= responses[i].length <= 1000
34+
1 <= responses[i][j].length <= 10
35+
responses[i][j] 仅由小写英文字母组成
36+
37+
中国时间 2025年04月26日 周六 22:30
38+
广州·中肿。术后第2天。
39+
哈希表计数。
40+
时间复杂度 O(L)。
41+
*/
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.List;
4+
5+
public class Solution3528 {
6+
private static final int MOD = (int) (1e9 + 7);
7+
private List<int[]>[] g; // to, wt
8+
private int[] ans;
9+
10+
public int[] baseUnitConversions(int[][] conversions) {
11+
int n = conversions.length + 1;
12+
g = new ArrayList[n];
13+
Arrays.setAll(g, e -> new ArrayList<>());
14+
for (int[] e : conversions) {
15+
g[e[0]].add(new int[]{e[1], e[2]});
16+
}
17+
18+
ans = new int[n];
19+
dfs(0, 1);
20+
return ans;
21+
}
22+
23+
private void dfs(int x, long mul) {
24+
ans[x] = (int) mul;
25+
for (int[] e : g[x]) {
26+
dfs(e[0], mul * e[1] % MOD);
27+
}
28+
}
29+
}
30+
/*
31+
3528. 单位转换 I
32+
https://leetcode.cn/problems/unit-conversion-i/description/
33+
34+
第 155 场双周赛 T2。
35+
36+
有 n 种单位,编号从 0 到 n - 1。给你一个二维整数数组 conversions,长度为 n - 1,其中 conversions[i] = [sourceUniti, targetUniti, conversionFactori] ,表示一个 sourceUniti 类型的单位等于 conversionFactori 个 targetUniti 类型的单位。
37+
请你返回一个长度为 n 的数组 baseUnitConversion,其中 baseUnitConversion[i] 表示 一个 0 类型单位等于多少个 i 类型单位。由于结果可能很大,请返回每个 baseUnitConversion[i] 对 10^9 + 7 取模后的值。
38+
提示:
39+
2 <= n <= 10^5
40+
conversions.length == n - 1
41+
0 <= sourceUniti, targetUniti < n
42+
1 <= conversionFactori <= 10^9
43+
保证单位 0 可以通过 唯一 的转换路径(不需要反向转换)转换为任何其他单位。
44+
45+
建图后 DFS。
46+
时间复杂度 O(n)。
47+
*/
Lines changed: 97 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,97 @@
1+
public class Solution3529 {
2+
public int countCells(char[][] grid, String pattern) {
3+
int m = grid.length;
4+
int n = grid[0].length;
5+
6+
char[] hText = new char[m * n];
7+
int idx = 0;
8+
for (int i = 0; i < m; i++) {
9+
for (int j = 0; j < n; j++) {
10+
hText[idx++] = grid[i][j];
11+
}
12+
}
13+
14+
char[] vText = new char[m * n];
15+
idx = 0;
16+
for (int j = 0; j < n; j++) {
17+
for (int i = 0; i < m; i++) {
18+
vText[idx++] = grid[i][j];
19+
}
20+
}
21+
22+
char[] pat = pattern.toCharArray();
23+
int[] pi = prefix_function(pat);
24+
int[] inPatternH = kmpSearch(hText, pat, pi);
25+
int[] inPatternV = kmpSearch(vText, pat, pi);
26+
27+
int ans = 0;
28+
for (int i = 0; i < m * n; i++) {
29+
if (inPatternH[i] > 0 && inPatternV[i % n * m + i / n] > 0) {
30+
ans++;
31+
}
32+
}
33+
return ans;
34+
}
35+
36+
private int[] prefix_function(char[] s) {
37+
int n = s.length;
38+
int[] pi = new int[n];
39+
for (int i = 1; i < n; i++) {
40+
int j = pi[i - 1];
41+
while (j > 0 && s[i] != s[j]) j = pi[j - 1];
42+
if (s[i] == s[j]) j++;
43+
pi[i] = j;
44+
}
45+
return pi;
46+
}
47+
48+
// 差分
49+
private int[] kmpSearch(char[] text, char[] pattern, int[] pi) {
50+
int n = text.length;
51+
int[] diff = new int[n + 1];
52+
int match = 0;
53+
for (int i = 0; i < n; i++) {
54+
char b = text[i];
55+
while (match > 0 && pattern[match] != b) {
56+
match = pi[match - 1];
57+
}
58+
if (pattern[match] == b) {
59+
match++;
60+
}
61+
if (match == pi.length) {
62+
diff[i - pi.length + 1]++;
63+
diff[i + 1]--;
64+
match = pi[match - 1];
65+
}
66+
}
67+
for (int i = 1; i < n; i++) {
68+
diff[i] += diff[i - 1];
69+
}
70+
return diff;
71+
}
72+
}
73+
/*
74+
3529. 统计水平子串和垂直子串重叠格子的数目
75+
https://leetcode.cn/problems/count-cells-in-overlapping-horizontal-and-vertical-substrings/description/
76+
77+
第 155 场双周赛 T3。
78+
79+
给你一个由字符组成的 m x n 矩阵 grid 和一个字符串 pattern。
80+
水平子串 是从左到右的一段连续字符序列。如果子串到达了某行的末尾,它将换行并从下一行的第一个字符继续。不会 从最后一行回到第一行。
81+
垂直子串 是从上到下的一段连续字符序列。如果子串到达了某列的底部,它将换列并从下一列的第一个字符继续。不会 从最后一列回到第一列。
82+
请统计矩阵中满足以下条件的单元格数量:
83+
- 该单元格必须属于 至少 一个等于 pattern 的水平子串,且属于 至少 一个等于 pattern 的垂直子串。
84+
返回满足条件的单元格数量。
85+
提示:
86+
m == grid.length
87+
n == grid[i].length
88+
1 <= m, n <= 1000
89+
1 <= m * n <= 10^5
90+
1 <= pattern.length <= m * n
91+
grid 和 pattern 仅由小写英文字母组成。
92+
93+
坐标转化 + KMP + 差分数组
94+
https://leetcode.cn/problems/count-cells-in-overlapping-horizontal-and-vertical-substrings/solutions/3663069/kmp-chai-fen-shu-zu-pythonjavacgo-by-end-h5mz/
95+
时间复杂度 O(mn)。
96+
rating 2116 (clist.by)
97+
*/
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
import java.util.Arrays;
2+
3+
public class Solution3530 {
4+
private int[] score, pre, memo;
5+
private int full;
6+
7+
public int maxProfit(int n, int[][] edges, int[] score) {
8+
this.score = score;
9+
pre = new int[n];
10+
for (int[] e : edges) {
11+
// r[1] 的先修课程集合
12+
pre[e[1]] |= 1 << e[0];
13+
}
14+
15+
full = (1 << n) - 1;
16+
memo = new int[1 << n];
17+
Arrays.fill(memo, -1);
18+
return dfs(full);
19+
}
20+
21+
private int dfs(int msk) {
22+
if (msk == 0) return 0; // 空集
23+
if (memo[msk] != -1) return memo[msk]; // 之前算过了
24+
int ci = full ^ msk; // i 的补集 complementary set
25+
int res = 0;
26+
int i = Integer.bitCount(ci);
27+
for (int j = 0; j < pre.length; j++) {
28+
// pre1[j] 在 i 的补集中,可以学(否则这学期一定不能学)
29+
if ((msk >> j & 1) == 1 && (pre[j] | ci) == ci) {
30+
res = Math.max(res,
31+
dfs(msk ^ (1 << j)) + score[j] * (i + 1));
32+
}
33+
}
34+
return memo[msk] = res;
35+
}
36+
}
37+
/*
38+
3530. 有向无环图中合法拓扑排序的最大利润
39+
https://leetcode.cn/problems/maximum-profit-from-valid-topological-order-in-dag/description/
40+
41+
第 155 场双周赛 T4。
42+
43+
给你一个由 n 个节点组成的有向无环图(DAG),节点编号从 0 到 n - 1,通过二维数组 edges 表示,其中 edges[i] = [ui, vi] 表示一条从节点 ui 指向节点 vi 的有向边。每个节点都有一个对应的 得分 ,由数组 score 给出,其中 score[i] 表示节点 i 的得分。
44+
你需要以 有效的拓扑排序 顺序处理这些节点。每个节点在处理顺序中被分配一个编号从 1 开始的位置。
45+
将每个节点的得分乘以其在拓扑排序中的位置,然后求和,得到的值称为 利润。
46+
请返回在所有合法拓扑排序中可获得的 最大利润 。
47+
拓扑排序 是一个对 DAG 中所有节点的线性排序,使得每条有向边 u → v 中,节点 u 都出现在 v 之前。
48+
提示:
49+
1 <= n == score.length <= 22
50+
1 <= score[i] <= 10^5
51+
0 <= edges.length <= n * (n - 1) / 2
52+
edges[i] == [ui, vi] 表示一条从 ui 到 vi 的有向边。
53+
0 <= ui, vi < n
54+
ui != vi
55+
输入图 保证 是一个 DAG。
56+
不存在重复的边。
57+
58+
排列型状压 DP。
59+
时间复杂度 O(m+n2^n)。
60+
相似题目: 1494. 并行课程 II
61+
https://leetcode.cn/problems/parallel-courses-ii/description/
62+
rating 2374 (clist.by)
63+
*/
Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
import java.util.Arrays;
2+
3+
public class Solution3531 {
4+
public int countCoveredBuildings(int n, int[][] buildings) {
5+
int[] rowMin = new int[n + 1];
6+
int[] rowMax = new int[n + 1];
7+
int[] colMin = new int[n + 1];
8+
int[] colMax = new int[n + 1];
9+
Arrays.fill(rowMin, n + 1);
10+
Arrays.fill(colMin, n + 1);
11+
12+
for (int[] p : buildings) {
13+
int x = p[0], y = p[1];
14+
rowMin[y] = Math.min(rowMin[y], x);
15+
rowMax[y] = Math.max(rowMax[y], x);
16+
colMin[x] = Math.min(colMin[x], y);
17+
colMax[x] = Math.max(colMax[x], y);
18+
}
19+
20+
int ans = 0;
21+
for (int[] p : buildings) {
22+
int x = p[0], y = p[1];
23+
if (rowMin[y] < x && x < rowMax[y] && colMin[x] < y && y < colMax[x]) {
24+
ans++;
25+
}
26+
}
27+
return ans;
28+
}
29+
}
30+
/*
31+
3531. 统计被覆盖的建筑
32+
https://leetcode.cn/problems/count-covered-buildings/description/
33+
34+
第 447 场周赛 T1。
35+
36+
给你一个正整数 n,表示一个 n x n 的城市,同时给定一个二维数组 buildings,其中 buildings[i] = [x, y] 表示位于坐标 [x, y] 的一个 唯一 建筑。
37+
如果一个建筑在四个方向(左、右、上、下)中每个方向上都至少存在一个建筑,则称该建筑 被覆盖 。
38+
返回 被覆盖 的建筑数量。
39+
提示:
40+
2 <= n <= 10^5
41+
1 <= buildings.length <= 10^5
42+
buildings[i] = [x, y]
43+
1 <= x, y <= n
44+
buildings 中所有坐标均 唯一 。
45+
46+
中国时间 2025年04月27日 周日 10:30
47+
广州·中肿。术后第3天。五一前的调休工作日。
48+
统计行列的最小值和最大值。
49+
时间复杂度 O(n + m)。
50+
*/
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
4+
public class Solution3532 {
5+
public boolean[] pathExistenceQueries(int n, int[] nums, int maxDiff, int[][] queries) {
6+
List<Integer> discontinuityPoints = new ArrayList<>();
7+
for (int i = 0; i < n - 1; i++) {
8+
if (nums[i + 1] - nums[i] > maxDiff) {
9+
discontinuityPoints.add(i); // 间断点
10+
}
11+
}
12+
13+
int q = queries.length;
14+
boolean[] ans = new boolean[q];
15+
for (int i = 0; i < q; i++) {
16+
int[] p = queries[i];
17+
ans[i] = (lowerBound(discontinuityPoints, p[0]) == lowerBound(discontinuityPoints, p[1]));
18+
}
19+
return ans;
20+
}
21+
22+
private int lowerBound(List<Integer> a, int key) {
23+
int l = 0, r = a.size();
24+
while (l < r) {
25+
int m = l + (r - l) / 2;
26+
if (a.get(m) >= key) r = m;
27+
else l = m + 1;
28+
}
29+
return l;
30+
}
31+
}
32+
/*
33+
3532. 针对图的路径存在性查询 I
34+
https://leetcode.cn/problems/path-existence-queries-in-a-graph-i/description/
35+
36+
第 447 场周赛 T2。
37+
38+
给你一个整数 n,表示图中的节点数量,这些节点按从 0 到 n - 1 编号。
39+
同时给你一个长度为 n 的整数数组 nums,该数组按 非递减 顺序排序,以及一个整数 maxDiff。
40+
如果满足 |nums[i] - nums[j]| <= maxDiff(即 nums[i] 和 nums[j] 的 绝对差 至多为 maxDiff),则节点 i 和节点 j 之间存在一条 无向边 。
41+
此外,给你一个二维整数数组 queries。对于每个 queries[i] = [ui, vi],需要判断节点 ui 和 vi 之间是否存在路径。
42+
返回一个布尔数组 answer,其中 answer[i] 等于 true 表示在第 i 个查询中节点 ui 和 vi 之间存在路径,否则为 false。
43+
提示:
44+
1 <= n == nums.length <= 10^5
45+
0 <= nums[i] <= 10^5
46+
nums 按 非递减 顺序排序。
47+
0 <= maxDiff <= 10^5
48+
1 <= queries.length <= 10^5
49+
queries[i] == [ui, vi]
50+
0 <= ui, vi < n
51+
52+
间断点 + 二分查找
53+
时间复杂度 O(n + qlogn)。
54+
*/

0 commit comments

Comments
(0)

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