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 586a2e3

Browse files
committed
第165场双周赛T1~T4 & 第467场周赛T1~T4 (8)
1 parent 76b3609 commit 586a2e3

16 files changed

+558
-0
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import java.util.HashSet;
2+
import java.util.Set;
3+
4+
public class Solution3678 {
5+
public int smallestAbsent(int[] nums) {
6+
int n = nums.length;
7+
int sum = 0;
8+
Set<Integer> set = new HashSet<>();
9+
for (int v : nums) {
10+
sum += v;
11+
set.add(v);
12+
}
13+
14+
int ans = (sum + n - 1) / n;
15+
if (ans * n == sum) ans++;
16+
ans = Math.max(ans, 1);
17+
while (set.contains(ans)) ans++;
18+
return ans;
19+
}
20+
}
21+
/*
22+
3678. 大于平均值的最小未出现正整数
23+
https://leetcode.cn/problems/smallest-absent-positive-greater-than-average/description/
24+
25+
第 165 场双周赛 T1。
26+
27+
给你一个整数数组 nums。
28+
返回 nums 中 严格大于 nums 中所有元素 平均值 的 最小未出现正整数。
29+
数组的 平均值 定义为数组中所有元素的总和除以元素的数量。
30+
提示:
31+
1 <= nums.length <= 100
32+
-100 <= nums[i] <= 100
33+
34+
阅读理解题。
35+
*/
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
import java.util.Arrays;
2+
3+
public class Solution3679 {
4+
public int minArrivalsToDiscard(int[] arrivals, int w, int m) {
5+
int n = arrivals.length;
6+
int mx = Arrays.stream(arrivals).max().orElseThrow();
7+
int[] cnt = new int[mx + 1];
8+
int ans = 0;
9+
boolean[] discarded = new boolean[n]; // 丢弃
10+
for (int i = 0; i < w; i++) {
11+
if (++cnt[arrivals[i]] > m) {
12+
ans++;
13+
--cnt[arrivals[i]];
14+
discarded[i] = true;
15+
}
16+
}
17+
for (int i = w; i < n; i++) {
18+
if (!discarded[i - w]) --cnt[arrivals[i - w]];
19+
if (++cnt[arrivals[i]] > m) {
20+
ans++;
21+
--cnt[arrivals[i]];
22+
discarded[i] = true;
23+
}
24+
}
25+
return ans;
26+
}
27+
}
28+
/*
29+
3679. 使库存平衡的最少丢弃次数
30+
https://leetcode.cn/problems/minimum-discards-to-balance-inventory/description/
31+
32+
第 165 场双周赛 T2。
33+
34+
给你两个整数 w 和 m,以及一个整数数组 arrivals,其中 arrivals[i] 表示第 i 天到达的物品类型(天数从 1 开始编号)。
35+
物品的管理遵循以下规则:
36+
- 每个到达的物品可以被 保留 或 丢弃 ,物品只能在到达当天被丢弃。
37+
- 对于每一天 i,考虑天数范围为 [max(1, i - w + 1), i](也就是直到第 i 天为止最近的 w 天):
38+
- 对于 任何 这样的时间窗口,在被保留的到达物品中,每种类型最多只能出现 m 次。
39+
- 如果在第 i 天保留该到达物品会导致其类型在该窗口中出现次数 超过 m 次,那么该物品必须被丢弃。
40+
返回为满足每个 w 天的窗口中每种类型最多出现 m 次,最少 需要丢弃的物品数量。
41+
提示:
42+
1 <= arrivals.length <= 10^5
43+
1 <= arrivals[i] <= 10^5
44+
1 <= w <= arrivals.length
45+
1 <= m <= w
46+
47+
固定大小的 滑动窗口。
48+
时间复杂度 O(n)
49+
*/
Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
public class Solution3680 {
2+
public int[][] generateSchedule(int n) {
3+
if (n < 5) {
4+
return new int[0][];
5+
}
6+
7+
int[][] ans = new int[n * (n - 1)][];
8+
int idx = 0;
9+
10+
// 处理 d=2,3,...,n-2
11+
for (int d = 2; d < n - 1; d++) {
12+
for (int i = 0; i < n; i++) {
13+
ans[idx++] = new int[]{i, (i + d) % n};
14+
}
15+
}
16+
17+
// 交错排列 d=1 与 d=n-1(或者说 d=-1)
18+
for (int i = 0; i < n; i++) {
19+
ans[idx++] = new int[]{i, (i + 1) % n};
20+
ans[idx++] = new int[]{(i + n - 1) % n, (i + n - 2) % n};
21+
}
22+
23+
return ans;
24+
}
25+
}
26+
/*
27+
3680. 生成赛程
28+
https://leetcode.cn/problems/generate-schedule/description/
29+
30+
第 165 场双周赛 T3。
31+
32+
给你一个整数 n,表示 n 支队伍。你需要生成一个赛程,使得:
33+
- 每支队伍与其他队伍 正好比赛两次:一次在主场,一次在客场。
34+
- 每天 只有一场 比赛;赛程是一个 连续的 天数列表,schedule[i] 表示第 i 天的比赛。
35+
- 没有队伍在 连续 两天内进行比赛。
36+
返回一个 2D 整数数组 schedule,其中 schedule[i][0] 表示主队,schedule[i][1] 表示客队。如果有多个满足条件的赛程,返回 其中任意一个 。
37+
如果没有满足条件的赛程,返回空数组。
38+
提示:
39+
2 <= n <= 50
40+
41+
幽默 T3。考察 构造题。
42+
听说这就是 贝格尔编排法,在国内排球比赛中广泛使用。
43+
时间复杂度 O(n^2)。
44+
*/
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
public class Solution3681 {
2+
public int maxXorSubsequences(int[] nums) {
3+
int[] base = new int[32];
4+
for (int num : nums) {
5+
for (int i = 31; i >= 0; i--) {
6+
if (((num >> i) & 1) == 1) {
7+
if (base[i] == 0) {
8+
base[i] = num;
9+
break;
10+
} else {
11+
num ^= base[i];
12+
}
13+
}
14+
}
15+
}
16+
int res = 0;
17+
for (int i = 31; i >= 0; i--) {
18+
if ((res ^ base[i]) > res) {
19+
res ^= base[i];
20+
}
21+
}
22+
return res;
23+
}
24+
}
25+
/*
26+
3681. 子序列最大 XOR 值
27+
https://leetcode.cn/problems/maximum-xor-of-subsequences/description/
28+
29+
第 165 场双周赛 T4。
30+
31+
给你一个长度为 n 的整数数组 nums,其中每个元素都是非负整数。
32+
选择 两个 子序列 nums(它们可以为空并且 允许重叠),每个子序列保留原始元素的顺序,并且定义:
33+
- X 是第一个子序列中所有元素的按位 XOR。
34+
- Y 是第二个子序列中所有元素的按位 XOR。
35+
返回 最大 的 X XOR Y 值。
36+
子序列 是通过删除某些或不删除任何元素,而不改变剩余元素的顺序,从另一个数组派生出的数组。
37+
注意:一个 空 子序列的 XOR 为 0。
38+
提示:
39+
2 <= nums.length <= 10^5
40+
0 <= nums[i] <= 10^9
41+
42+
方法思路
43+
1.问题分析:我们需要选择两个子序列,使得它们的异或值X和Y的异或结果最大。通过观察,可以发现最终结果等价于从数组中选择一个子集,使得该子集的异或和最大。
44+
2.关键 insight:无论元素如何分配到两个子序列中,最终结果总是等于所选子集的异或和。因此,问题转化为求数组的最大异或子集。
45+
3.算法选择:使用线性基数据结构来高效计算最大异或子集。线性基能够处理大量数据并快速找到最大异或值。
46+
4.复杂度分析:线性基的构建和查询过程的时间复杂度均为O(n * 32),其中n是数组长度,32是数字的位数上限。这使得算法能够高效处理大规模数据。
47+
https://chat.deepseek.com/a/chat/s/9a482b5d-a8ae-446b-bf8b-5e291acede0e
48+
*/
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
public class Solution3683 {
2+
public int earliestTime(int[][] tasks) {
3+
int ans = Integer.MAX_VALUE;
4+
for (int[] t : tasks) {
5+
ans = Math.min(ans, t[0] + t[1]);
6+
}
7+
return ans;
8+
}
9+
}
10+
/*
11+
3683. 完成一个任务的最早时间
12+
https://leetcode.cn/problems/earliest-time-to-finish-one-task/description/
13+
14+
第 467 场周赛 T1。
15+
16+
给你一个二维整数数组 tasks,其中 tasks[i] = [si, ti]。
17+
数组中的每个 [si, ti] 表示一个任务,该任务的开始时间为 si,完成该任务需要 ti 个时间单位。
18+
返回至少完成一个任务的最早时间。
19+
提示:
20+
1 <= tasks.length <= 100
21+
tasks[i] = [si, ti]
22+
1 <= si, ti <= 100
23+
24+
遍历。
25+
时间复杂度 O(n)。
26+
*/
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import java.util.Arrays;
2+
3+
public class Solution3684 {
4+
public int[] maxKDistinct(int[] nums, int k) {
5+
int[] a = Arrays.stream(nums).distinct().sorted().toArray();
6+
int ansLen = Math.min(k, a.length);
7+
int[] ans = new int[ansLen];
8+
for (int i = 0; i < ansLen; i++) {
9+
ans[i] = a[a.length - 1 - i];
10+
}
11+
return ans;
12+
}
13+
}
14+
/*
15+
3684. 至多 K 个不同元素的最大和
16+
https://leetcode.cn/problems/maximize-sum-of-at-most-k-distinct-elements/description/
17+
18+
第 467 场周赛 T2。
19+
20+
给你一个 正整数 数组 nums 和一个整数 k。
21+
从 nums 中选择最多 k 个元素,使它们的和最大化。但是,所选的数字必须 互不相同 。
22+
返回一个包含所选数字的数组,数组中的元素按 严格递减 顺序排序。
23+
提示:
24+
1 <= nums.length <= 100
25+
1 <= nums[i] <= 10^9
26+
1 <= k <= nums.length
27+
28+
哈希表去重,贪心。
29+
时间复杂度 O(nlogn)。
30+
*/
Lines changed: 84 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,84 @@
1+
public class Solution3685 {
2+
public boolean[] subsequenceSumAfterCapping(int[] nums, int k) {
3+
int n = nums.length;
4+
boolean[] ans = new boolean[n];
5+
int[] cnt = new int[n + 1];
6+
for (int num : nums) {
7+
cnt[num]++;
8+
}
9+
int[] suf = new int[n + 2];
10+
suf[n] = 0;
11+
for (int i = n - 1; i >= 1; i--) {
12+
suf[i] = suf[i + 1] + cnt[i + 1];
13+
}
14+
boolean[] f = new boolean[k + 1];
15+
f[0] = true;
16+
int maxX = Math.min(n, k);
17+
for (int x = 1; x <= maxX; x++) {
18+
int c = cnt[x];
19+
if (c > 0) {
20+
int num = c;
21+
int power = 1;
22+
while (power <= num) {
23+
int s = power;
24+
int total = s * x;
25+
if (total <= k) {
26+
for (int j = k; j >= total; j--) {
27+
if (f[j - total]) {
28+
f[j] = true;
29+
}
30+
}
31+
}
32+
num -= s;
33+
power <<= 1;
34+
}
35+
if (num > 0) {
36+
int total = num * x;
37+
if (total <= k) {
38+
for (int j = k; j >= total; j--) {
39+
if (f[j - total]) {
40+
f[j] = true;
41+
}
42+
}
43+
}
44+
}
45+
}
46+
int m = suf[x];
47+
int maxT = Math.min(m, k / x);
48+
boolean found = false;
49+
for (int t = 0; t <= maxT; t++) {
50+
int remain = k - t * x;
51+
if (remain < 0) {
52+
break;
53+
}
54+
if (f[remain]) {
55+
found = true;
56+
break;
57+
}
58+
}
59+
ans[x - 1] = found;
60+
}
61+
for (int x = maxX + 1; x <= n; x++) {
62+
ans[x - 1] = f[k];
63+
}
64+
return ans;
65+
}
66+
}
67+
/*
68+
3685. 含上限元素的子序列和
69+
https://leetcode.cn/problems/subsequence-sum-after-capping-elements/description/
70+
71+
第 467 场周赛 T3。
72+
73+
给你一个大小为 n 的整数数组 nums 和一个正整数 k。
74+
通过将每个元素 nums[i] 替换为 min(nums[i], x),可以得到一个由值 x 限制(capped)的数组。
75+
对于从 1 到 n 的每个整数 x,确定是否可以从由 x 限制的数组中选择一个 子序列,使所选元素的和 恰好 为 k。
76+
返回一个下标从 0 开始的布尔数组 answer,其大小为 n,其中 answer[i] 为 true 表示当 x = i + 1 时可以选出满足要求的子序列;否则为 false。
77+
子序列 是一个从数组中通过删除一些或不删除任何元素(且不改变剩余元素顺序)派生出来的 非空 数组。
78+
提示:
79+
1 <= n == nums.length <= 4000
80+
1 <= nums[i] <= n
81+
1 <= k <= 4000
82+
83+
https://yuanbao.tencent.com/chat/naQivTmsDa/46fb2110-a302-44b3-b5eb-f5c9f557ebef
84+
*/
Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
public class Solution3686 {
2+
private static final int MOD = (int) (1e9 + 7);
3+
4+
public int countStableSubsequences(int[] nums) {
5+
long dp0 = 1;
6+
long dp10 = 0, dp11 = 0;
7+
long dp20 = 0, dp21 = 0;
8+
9+
for (int num : nums) {
10+
int x = num % 2;
11+
long old0 = dp0;
12+
long old10 = dp10, old11 = dp11;
13+
long old20 = dp20, old21 = dp21;
14+
15+
if (x == 0) {
16+
dp10 = (dp10 + old0) % MOD;
17+
dp20 = (dp20 + old10) % MOD;
18+
dp10 = (dp10 + old11) % MOD;
19+
dp10 = (dp10 + old21) % MOD;
20+
} else {
21+
dp11 = (dp11 + old0) % MOD;
22+
dp11 = (dp11 + old10) % MOD;
23+
dp21 = (dp21 + old11) % MOD;
24+
dp11 = (dp11 + old20) % MOD;
25+
}
26+
}
27+
28+
long ans = (dp10 + dp11 + dp20 + dp21) % MOD;
29+
return (int) ans;
30+
}
31+
}
32+
/*
33+
3686. 稳定子序列的数量
34+
https://leetcode.cn/problems/number-of-stable-subsequences/description/
35+
36+
第 467 场周赛 T4。
37+
38+
给你一个整数数组 nums。
39+
如果一个 子序列 中 不存在连续三个 元素奇偶性相同(仅考虑该子序列内),则称该子序列为稳定子序列 。
40+
请返回所有稳定子序列的数量。
41+
由于结果可能非常大,请将答案对 10^9 + 7 取余数后返回。
42+
子序列 是一个从数组中通过删除某些元素(或不删除任何元素),并保持剩余元素相对顺序不变的 非空 数组。
43+
提示:
44+
1 <= nums.length <= 10^5
45+
1 <= nums[i] <= 10^5
46+
47+
方法思路
48+
1.问题分析:问题要求统计所有非空子序列,其中没有三个连续元素具有相同的奇偶性。关键在于处理每个元素时,动态跟踪以奇数或偶数结尾的子序列数量,并确保不形成三个连续相同奇偶性的序列。
49+
2.动态编程状态:使用以下状态来跟踪子序列:
50+
dp0:空子序列的计数(始终为1)。
51+
dp10和dp11:以单个偶数或奇数结尾的子序列计数。
52+
dp20和dp21:以两个连续偶数或奇数结尾的子序列计数。
53+
3.状态转移:对于数组中的每个元素,根据其奇偶性更新状态:
54+
偶数元素(x=0):更新状态以反映新增的偶数元素,确保不形成三个连续偶数。
55+
奇数元素(x=1):类似地更新状态以处理新增的奇数元素,避免三个连续奇数。
56+
4.结果计算:最终结果是所有有效非空子序列的计数之和,即dp10 + dp11 + dp20 + dp21,取模 10^9 + 7
57+
https://chat.deepseek.com/a/chat/s/71b9d0e2-bfff-4da9-86b6-495ff7d20a3b
58+
*/

0 commit comments

Comments
(0)

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