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 d877391

Browse files
committed
第454场周赛T1~T4 (4)
1 parent 4adca3e commit d877391

File tree

8 files changed

+396
-0
lines changed

8 files changed

+396
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
public class Solution3582 {
2+
public String generateTag(String caption) {
3+
caption = ("#" + caption.strip()).toLowerCase();
4+
StringBuilder ans = new StringBuilder("#");
5+
for (int i = 1; i < caption.length(); i++) {
6+
char c = caption.charAt(i);
7+
if (c == ' ') continue;
8+
if (caption.charAt(i - 1) == ' ') {
9+
ans.append(Character.toUpperCase(c));
10+
} else {
11+
ans.append(c);
12+
}
13+
}
14+
return ans.substring(0, Math.min(100, ans.length()));
15+
}
16+
}
17+
/*
18+
3582. 为视频标题生成标签
19+
https://leetcode.cn/problems/generate-tag-for-video-caption/description/
20+
21+
第 454 场周赛 T1。
22+
23+
给你一个字符串 caption,表示一个视频的标题。
24+
需要按照以下步骤 按顺序 生成一个视频的 有效标签 :
25+
1.将 所有单词 组合为单个 驼峰命名字符串 ,并在前面加上 '#'。驼峰命名字符串 指的是除第一个单词外,其余单词的首字母大写,且每个单词的首字母之后的字符必须是小写。
26+
2.移除 所有不是英文字母的字符,但 保留 第一个字符 '#'。
27+
3.将结果 截断 为最多 100 个字符。
28+
对 caption 执行上述操作后,返回生成的 标签 。
29+
提示:
30+
1 <= caption.length <= 150
31+
caption 仅由英文字母和 ' ' 组成。
32+
33+
模拟。WA了5次,细节是魔鬼。
34+
时间复杂度 O(n)。
35+
*/
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import java.util.HashMap;
2+
import java.util.Map;
3+
4+
public class Solution3583 {
5+
private static final int MOD = (int) (1e9 + 7);
6+
7+
public int specialTriplets(int[] nums) {
8+
int n = nums.length;
9+
int[] lcnt = new int[n];
10+
Map<Integer, Integer> cnt = new HashMap<>();
11+
for (int i = 0; i < n; i++) {
12+
lcnt[i] = cnt.getOrDefault(nums[i] * 2, 0);
13+
cnt.merge(nums[i], 1, Integer::sum);
14+
}
15+
16+
int[] rcnt = new int[n];
17+
cnt.clear();
18+
for (int i = n - 1; i >= 0; i--) {
19+
rcnt[i] = cnt.getOrDefault(nums[i] * 2, 0);
20+
cnt.merge(nums[i], 1, Integer::sum);
21+
}
22+
23+
long ans = 0;
24+
for (int i = 1; i + 1 < n; i++) {
25+
ans = (ans + (long) lcnt[i] * rcnt[i]) % MOD;
26+
}
27+
return (int) ans;
28+
}
29+
}
30+
/*
31+
3583. 统计特殊三元组
32+
https://leetcode.cn/problems/count-special-triplets/description/
33+
34+
第 454 场周赛 T2。
35+
36+
给你一个整数数组 nums。
37+
特殊三元组 定义为满足以下条件的下标三元组 (i, j, k):
38+
- 0 <= i < j < k < n,其中 n = nums.length
39+
- nums[i] == nums[j] * 2
40+
- nums[k] == nums[j] * 2
41+
返回数组中 特殊三元组 的总数。
42+
由于答案可能非常大,请返回结果对 10^9 + 7 取余数后的值。
43+
提示:
44+
3 <= n == nums.length <= 10^5
45+
0 <= nums[i] <= 10^5
46+
47+
前后缀分解 + 枚举中间。
48+
时间复杂度 O(n)。
49+
*/
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
public class Solution3584 {
2+
private static final long INF = (long) 1e18;
3+
4+
public long maximumProduct(int[] nums, int m) {
5+
int n = nums.length;
6+
if (m == 1) {
7+
long ans = 0;
8+
for (int x : nums) ans = Math.max(ans, (long) x * x);
9+
return ans;
10+
}
11+
int k = m - 1;
12+
13+
int[] max_suffix = new int[n];
14+
int[] min_suffix = new int[n];
15+
max_suffix[n - 1] = nums[n - 1];
16+
min_suffix[n - 1] = nums[n - 1];
17+
18+
for (int i = n - 2; i >= 0; i--) {
19+
max_suffix[i] = Math.max(nums[i], max_suffix[i + 1]);
20+
min_suffix[i] = Math.min(nums[i], min_suffix[i + 1]);
21+
}
22+
23+
long candidate;
24+
long max_prod = -INF;
25+
for (int i = 0; i + k < n; i++) {
26+
int start = i + k;
27+
if (nums[i] >= 0) {
28+
candidate = (long) nums[i] * max_suffix[start];
29+
} else {
30+
candidate = (long) nums[i] * min_suffix[start];
31+
}
32+
max_prod = Math.max(max_prod, candidate);
33+
}
34+
35+
return max_prod;
36+
}
37+
}
38+
/*
39+
3584. 子序列首尾元素的最大乘积
40+
https://leetcode.cn/problems/maximum-product-of-first-and-last-elements-of-a-subsequence/description/
41+
42+
第 454 场周赛 T3。
43+
44+
给你一个整数数组 nums 和一个整数 m。
45+
返回任意大小为 m 的 子序列 中首尾元素乘积的最大值。
46+
子序列 是可以通过删除原数组中的一些元素(或不删除任何元素),且不改变剩余元素顺序而得到的数组。
47+
提示:
48+
1 <= nums.length <= 10^5
49+
-10^5 <= nums[i] <= 10^5
50+
1 <= m <= nums.length
51+
52+
预处理后缀 + 贪心。
53+
时间复杂度 O(n)。
54+
*/
Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
import java.util.ArrayList;
2+
import java.util.Arrays;
3+
import java.util.List;
4+
5+
public class Solution3585 {
6+
private List<int[]>[] g;
7+
private int dfn;
8+
private int[][] nodes; // l, r
9+
private final int mx = 17;
10+
private int[][] pa;
11+
private int[] dep;
12+
private long[] sum_to_root;
13+
14+
public int[] findMedian(int n, int[][] edges, int[][] queries) {
15+
g = new ArrayList[n];
16+
Arrays.setAll(g, e -> new ArrayList<>());
17+
for (int[] e : edges) {
18+
g[e[0]].add(new int[]{e[1], e[2]});
19+
g[e[1]].add(new int[]{e[0], e[2]});
20+
}
21+
dfn = 0;
22+
nodes = new int[n][2];
23+
pa = new int[n][mx];
24+
dep = new int[n];
25+
sum_to_root = new long[n];
26+
build(0, -1);
27+
for (int i = 0; i + 1 < mx; i++) {
28+
for (int v = 0; v < pa.length; v++) {
29+
int p = pa[v][i];
30+
if (p != -1) {
31+
pa[v][i + 1] = pa[p][i];
32+
} else {
33+
pa[v][i + 1] = -1;
34+
}
35+
}
36+
}
37+
38+
int[] ans = new int[queries.length];
39+
for (int i = 0; i < queries.length; i++) {
40+
int u = queries[i][0], v = queries[i][1];
41+
long total = get_path_sum(u, v);
42+
int lcaNode = getLCA(u, v);
43+
int current1 = u;
44+
for (int k = mx - 1; k >= 0; k--) {
45+
int next_node = pa[current1][k];
46+
if (next_node == -1) continue;
47+
if (dep[next_node] < dep[lcaNode]) continue;
48+
if (2 * (sum_to_root[u] - sum_to_root[next_node]) < total) {
49+
current1 = next_node;
50+
}
51+
}
52+
if (current1 != lcaNode) {
53+
ans[i] = pa[current1][0];
54+
} else {
55+
int candidate2 = v;
56+
for (int k = mx - 1; k >= 0; k--) {
57+
int next_node = pa[candidate2][k];
58+
if (next_node == -1) continue;
59+
if (dep[next_node] <= dep[lcaNode]) continue;
60+
if (2 * (sum_to_root[u] + sum_to_root[next_node] - 2 * sum_to_root[lcaNode]) >= total) {
61+
candidate2 = next_node;
62+
}
63+
}
64+
ans[i] = candidate2;
65+
}
66+
}
67+
return ans;
68+
}
69+
70+
long get_path_sum(int u, int v) {
71+
int ancestor = getLCA(u, v);
72+
return sum_to_root[u] + sum_to_root[v] - 2 * sum_to_root[ancestor];
73+
}
74+
75+
int build(int v, int fa) {
76+
dfn++;
77+
nodes[v][0] = dfn;
78+
pa[v][0] = fa;
79+
int sz = 1;
80+
for (int[] p : g[v]) {
81+
int w = p[0], wt = p[1];
82+
if (w != fa) {
83+
dep[w] = dep[v] + 1;
84+
sum_to_root[w] = sum_to_root[v] + wt;
85+
sz += build(w, v);
86+
}
87+
}
88+
nodes[v][1] = nodes[v][0] + sz - 1;
89+
return sz;
90+
}
91+
92+
int uptoDep(int v, int d) {
93+
for (int k = dep[v] - d; k > 0; k &= k - 1) {
94+
v = pa[v][Integer.numberOfTrailingZeros(k)];
95+
}
96+
return v;
97+
}
98+
99+
int getLCA(int v, int w) {
100+
if (dep[v] > dep[w]) {
101+
int tmp = v;
102+
v = w;
103+
w = tmp;
104+
}
105+
w = uptoDep(w, dep[v]);
106+
if (w == v) return v;
107+
for (int i = mx - 1; i >= 0; i--) {
108+
if (pa[v][i] != pa[w][i]) {
109+
v = pa[v][i];
110+
w = pa[w][i];
111+
}
112+
}
113+
return pa[v][0];
114+
}
115+
}
116+
/*
117+
3585. 树中找到带权中位节点
118+
https://leetcode.cn/problems/find-weighted-median-node-in-tree/description/
119+
120+
第 454 场周赛 T4。
121+
122+
给你一个整数 n,以及一棵 无向带权 树,根节点为节点 0,树中共有 n 个节点,编号从 0 到 n - 1。该树由一个长度为 n - 1 的二维数组 edges 表示,其中 edges[i] = [ui, vi, wi] 表示存在一条从节点 ui 到 vi 的边,权重为 wi。
123+
带权中位节点 定义为从 ui 到 vi 路径上的 第一个 节点 x,使得从 ui 到 x 的边权之和 大于等于 该路径总权值和的一半。
124+
给你一个二维整数数组 queries。对于每个 queries[j] = [uj, vj],求出从 uj 到 vj 路径上的带权中位节点。
125+
返回一个数组 ans,其中 ans[j] 表示查询 queries[j] 的带权中位节点编号。
126+
提示:
127+
2 <= n <= 10^5
128+
edges.length == n - 1
129+
edges[i] == [ui, vi, wi]
130+
0 <= ui, vi < n
131+
1 <= wi <= 10^9
132+
1 <= queries.length <= 10^5
133+
queries[j] == [uj, vj]
134+
0 <= uj, vj < n
135+
输入保证 edges 表示一棵合法的树。
136+
137+
最近公共祖先 LCA + 树上倍增。
138+
先从 u 点倍增到 lca 点,若干未能得到答案,那么再从 lca 点倍增到 v 点(反向)。
139+
时间复杂度 O((n+q)logn)。
140+
rating 2399 (clist.by)
141+
*/
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 Solution3582Tests {
5+
private final Solution3582 solution3582 = new Solution3582();
6+
7+
@Test
8+
public void example1() {
9+
String caption = "Leetcode daily streak achieved";
10+
String expected = "#leetcodeDailyStreakAchieved";
11+
Assertions.assertEquals(expected, solution3582.generateTag(caption));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
String caption = "can I Go There";
17+
String expected = "#canIGoThere";
18+
Assertions.assertEquals(expected, solution3582.generateTag(caption));
19+
}
20+
21+
@Test
22+
public void example3() {
23+
String caption = "hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh";
24+
String expected = "#hhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh";
25+
Assertions.assertEquals(expected, solution3582.generateTag(caption));
26+
}
27+
}
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 Solution3583Tests {
5+
private final Solution3583 solution3583 = new Solution3583();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {6, 3, 6};
10+
int expected = 1;
11+
Assertions.assertEquals(expected, solution3583.specialTriplets(nums));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[] nums = {0, 1, 0, 0};
17+
int expected = 1;
18+
Assertions.assertEquals(expected, solution3583.specialTriplets(nums));
19+
}
20+
21+
@Test
22+
public void example3() {
23+
int[] nums = {8, 4, 2, 8, 4};
24+
int expected = 2;
25+
Assertions.assertEquals(expected, solution3583.specialTriplets(nums));
26+
}
27+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3584Tests {
5+
private final Solution3584 solution3584 = new Solution3584();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {-1, -9, 2, 3, -2, -3, 1};
10+
int m = 1;
11+
long expected = 81;
12+
Assertions.assertEquals(expected, solution3584.maximumProduct(nums, m));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
int[] nums = {1, 3, -5, 5, 6, -4};
18+
int m = 3;
19+
long expected = 20;
20+
Assertions.assertEquals(expected, solution3584.maximumProduct(nums, m));
21+
}
22+
23+
@Test
24+
public void example3() {
25+
int[] nums = {2, -1, 2, -6, 5, 2, -5, 7};
26+
int m = 2;
27+
long expected = 35;
28+
Assertions.assertEquals(expected, solution3584.maximumProduct(nums, m));
29+
}
30+
}

0 commit comments

Comments
(0)

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