Skip to content

Commit 6b5d8e5

Browse files
committed
第429场周赛T1~T4 (4)
1 parent 3a4b8fc commit 6b5d8e5

File tree

8 files changed

+239
-0
lines changed

8 files changed

+239
-0
lines changed
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
import java.util.HashSet;
2+
import java.util.Set;
3+
4+
public class Solution3396 {
5+
public int minimumOperations(int[] nums) {
6+
int n = nums.length;
7+
Set<Integer> set = new HashSet<>();
8+
for (int i = n - 1; i >= 0; i--) {
9+
if (set.contains(nums[i])) break;
10+
set.add(nums[i]);
11+
}
12+
return ((n - set.size()) + 2) / 3;
13+
}
14+
}
15+
/*
16+
3396. 使数组元素互不相同所需的最少操作次数
17+
https://leetcode.cn/problems/minimum-number-of-operations-to-make-elements-in-array-distinct/description/
18+
19+
第 429 场周赛 T1。
20+
21+
给你一个整数数组 nums,你需要确保数组中的元素 互不相同 。为此,你可以执行以下操作任意次:
22+
- 从数组的开头移除 3 个元素。如果数组中元素少于 3 个,则移除所有剩余元素。
23+
注意:空数组也视作为数组元素互不相同。返回使数组元素互不相同所需的 最少操作次数 。
24+
提示:
25+
1 <= nums.length <= 100
26+
1 <= nums[i] <= 100
27+
28+
后往前枚举,数组元素互不相同 的长度 L。则要删去 n-L。
29+
答案为 ceil( (n-L) / 3 )
30+
*/
Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
import java.util.Arrays;
2+
3+
public class Solution3397 {
4+
public int maxDistinctElements(int[] nums, int k) {
5+
int n = nums.length;
6+
Arrays.sort(nums);
7+
int preR = Integer.MIN_VALUE;
8+
int ans = 0;
9+
int i = 0;
10+
while (i < n) {
11+
// 分组循环
12+
int st = i;
13+
for (i++; i < n && nums[i] == nums[st]; i++) {
14+
}
15+
int span = i - st;
16+
int L = nums[st] - k;
17+
int R = nums[st] + k;
18+
// [max(L, preR+1), R]
19+
int maxL = Math.max(L, preR);
20+
int add = Math.min(R - maxL + 1, span);
21+
ans += add;
22+
preR = maxL + add;
23+
}
24+
return ans;
25+
}
26+
}
27+
/*
28+
3397. 执行操作后不同元素的最大数量
29+
https://leetcode.cn/problems/maximum-number-of-distinct-elements-after-operations/description/
30+
31+
第 429 场周赛 T2。
32+
33+
给你一个整数数组 nums 和一个整数 k。
34+
你可以对数组中的每个元素 最多 执行 一次 以下操作:
35+
- 将一个在范围 [-k, k] 内的整数加到该元素上。
36+
返回执行这些操作后,nums 中可能拥有的不同元素的 最大 数量。
37+
提示:
38+
1 <= nums.length <= 10^5
39+
1 <= nums[i] <= 10^9
40+
0 <= k <= 10^9
41+
42+
贪心 + 排序 + 分组循环。
43+
*/
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
public class Solution3398 {
2+
}
3+
/*
4+
3398. 字符相同的最短子字符串 I
5+
https://leetcode.cn/problems/smallest-substring-with-identical-characters-i/description/
6+
7+
第 429 场周赛 T3。
8+
9+
给你一个长度为 n 的二进制字符串 s 和一个整数 numOps。
10+
你可以对 s 执行以下操作,最多 numOps 次:
11+
- 选择任意下标 i(其中 0 <= i < n),并 翻转 s[i],即如果 s[i] == '1',则将 s[i] 改为 '0',反之亦然。
12+
你需要 最小化 s 的最长 相同 子字符串 的长度,相同子字符串 是指子字符串中的所有字符都 相同。
13+
返回执行所有操作后可获得的 最小 长度。
14+
提示:
15+
1 <= n == s.length <= 1000
16+
s 仅由 '0' 和 '1' 组成。
17+
0 <= numOps <= n
18+
19+
同: 3399. 字符相同的最短子字符串 II
20+
https://leetcode.cn/problems/smallest-substring-with-identical-characters-ii/description/
21+
rating 2307 (clist.by)
22+
*/
Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
public class Solution3399 {
2+
public int minLength(String s, int numOps) {
3+
int n = s.length();
4+
char[] cs = s.toCharArray();
5+
if (check(cs, numOps, 0) || check(cs, numOps, 1)) return 1;
6+
7+
int left = 2;
8+
int right = n;
9+
while (left < right) {
10+
int mid = left + (right - left) / 2;
11+
// 边界二分 F, F,..., F, [T, T,..., T]
12+
// ----------------------^
13+
if (checkMid(cs, numOps, mid)) {
14+
right = mid;
15+
} else {
16+
left = mid + 1;
17+
}
18+
}
19+
return left;
20+
}
21+
22+
private boolean check(char[] s, int numOps, int x) {
23+
int cnt = 0;
24+
for (int i = 0; i < s.length; i++) if (s[i] % 2 != (i + x) % 2) cnt++;
25+
return cnt <= numOps;
26+
}
27+
28+
private boolean checkMid(char[] s, int numOps, int mid) {
29+
int needOps = 0;
30+
int i = 0;
31+
while (i < s.length) {
32+
int st = i;
33+
for (i++; i < s.length && s[i] == s[st]; i++) {
34+
}
35+
int span = i - st;
36+
needOps += span / (mid + 1);
37+
}
38+
return needOps <= numOps;
39+
}
40+
}
41+
/*
42+
3399. 字符相同的最短子字符串 II
43+
https://leetcode.cn/problems/smallest-substring-with-identical-characters-ii/description/
44+
45+
第 429 场周赛 T4。
46+
47+
给你一个长度为 n 的二进制字符串 s 和一个整数 numOps。
48+
你可以对 s 执行以下操作,最多 numOps 次:
49+
- 选择任意下标 i(其中 0 <= i < n),并 翻转 s[i],即如果 s[i] == '1',则将 s[i] 改为 '0',反之亦然。
50+
你需要 最小化 s 的最长 相同 子字符串 的长度,相同子字符串是指子字符串中的所有字符都相同。
51+
返回执行所有操作后可获得的 最小 长度。
52+
提示:
53+
1 <= n == s.length <= 10^5
54+
s 仅由 '0' 和 '1' 组成。
55+
0 <= numOps <= n
56+
57+
二分 + 贪心 + 分类讨论。
58+
但 x=1 的情况就不能使用这个调整了。考虑 s = 0110,无论是第一个 1 还是第二个 1,都位于这一段的边界,可能会影响到相邻段的答案,
59+
因此不能直接应用这个贪心。好在 x=1 的情况下,最终的字符串只可能有两种:要么 0101...,要么 1010...。
60+
我们把最终字符串和 s 进行比较,看是不是至多有 numOps 个字符不同即可。
61+
rating 2382 (clist.by)
62+
*/
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 Solution3396Tests {
5+
private final Solution3396 solution3396 = new Solution3396();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {1, 2, 3, 4, 2, 3, 3, 5, 7};
10+
int expected = 2;
11+
Assertions.assertEquals(expected, solution3396.minimumOperations(nums));
12+
}
13+
14+
@Test
15+
public void example2() {
16+
int[] nums = {4, 5, 6, 4, 4};
17+
int expected = 2;
18+
Assertions.assertEquals(expected, solution3396.minimumOperations(nums));
19+
}
20+
21+
@Test
22+
public void example3() {
23+
int[] nums = {6, 7, 8, 9};
24+
int expected = 0;
25+
Assertions.assertEquals(expected, solution3396.minimumOperations(nums));
26+
}
27+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution3397Tests {
5+
private final Solution3397 solution3397 = new Solution3397();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums = {1, 2, 2, 3, 3, 4};
10+
int k = 2;
11+
int expected = 6;
12+
Assertions.assertEquals(expected, solution3397.maxDistinctElements(nums, k));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
int[] nums = {4, 4, 4, 4};
18+
int k = 1;
19+
int expected = 3;
20+
Assertions.assertEquals(expected, solution3397.maxDistinctElements(nums, k));
21+
}
22+
}
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
public class Solution3398Tests {
2+
3+
}
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 Solution3399Tests {
5+
private final Solution3399 solution3399 = new Solution3399();
6+
7+
@Test
8+
public void example1() {
9+
String s = "000001";
10+
int numOps = 1;
11+
int expected = 2;
12+
Assertions.assertEquals(expected, solution3399.minLength(s, numOps));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
String s = "0000";
18+
int numOps = 2;
19+
int expected = 1;
20+
Assertions.assertEquals(expected, solution3399.minLength(s, numOps));
21+
}
22+
23+
@Test
24+
public void example3() {
25+
String s = "0101";
26+
int numOps = 0;
27+
int expected = 1;
28+
Assertions.assertEquals(expected, solution3399.minLength(s, numOps));
29+
}
30+
}

0 commit comments

Comments
 (0)