Skip to content

Commit 6ddbdcc

Browse files
committed
第96场双周赛T1~T4 & 第329场周赛T1~T3 (7)
1 parent 325a35e commit 6ddbdcc

14 files changed

+475
-0
lines changed
Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
public class Solution2540 {
2+
public int getCommon(int[] nums1, int[] nums2) {
3+
int n = nums1.length;
4+
int m = nums2.length;
5+
int i = 0;
6+
int j = 0;
7+
while (i < n && j < m) {
8+
if (nums1[i] == nums2[j]) {
9+
return nums1[i];
10+
} else if (nums1[i] > nums2[j]) {
11+
j++;
12+
} else {
13+
i++;
14+
}
15+
}
16+
return -1;
17+
}
18+
}
19+
/*
20+
2540. 最小公共值
21+
https://leetcode.cn/problems/minimum-common-value/
22+
23+
第 96 场双周赛 T1。
24+
25+
给你两个整数数组 nums1 和 nums2 ,它们已经按非降序排序,请你返回两个数组的 最小公共整数 。如果两个数组 nums1 和 nums2 没有公共整数,请你返回 -1 。
26+
如果一个整数在两个数组中都 至少出现一次 ,那么这个整数是数组 nums1 和 nums2 公共 的。
27+
提示:
28+
1 <= nums1.length, nums2.length <= 10^5
29+
1 <= nums1[i], nums2[j] <= 10^9
30+
nums1 和 nums2 都是 非降序 的。
31+
32+
双指针
33+
*/
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
import java.util.Arrays;
2+
3+
public class Solution2541 {
4+
public long minOperations(int[] nums1, int[] nums2, int k) {
5+
// 特判
6+
if (k == 0) {
7+
return Arrays.equals(nums1, nums2) ? 0 : -1;
8+
}
9+
10+
int n = nums1.length;
11+
long add = 0;
12+
long sub = 0;
13+
for (int i = 0; i < n; i++) {
14+
if (nums1[i] < nums2[i]) {
15+
int d = nums2[i] - nums1[i];
16+
if (d % k != 0) {
17+
return -1;
18+
} else {
19+
add += d / k;
20+
}
21+
} else if (nums1[i] > nums2[i]) {
22+
int d = nums1[i] - nums2[i];
23+
if (d % k != 0) {
24+
return -1;
25+
} else {
26+
sub += d / k;
27+
}
28+
}
29+
}
30+
return add == sub ? add : -1;
31+
}
32+
}
33+
/*
34+
2541. 使数组中所有元素相等的最小操作数 II
35+
https://leetcode.cn/problems/minimum-operations-to-make-array-equal-ii/
36+
37+
第 96 场双周赛 T2。
38+
39+
给你两个整数数组 nums1 和 nums2 ,两个数组长度都是 n ,再给你一个整数 k 。你可以对数组 nums1 进行以下操作:
40+
- 选择两个下标 i 和 j ,将 nums1[i] 增加 k ,将 nums1[j] 减少 k 。换言之,nums1[i] = nums1[i] + k 且 nums1[j] = nums1[j] - k 。
41+
如果对于所有满足 0 <= i < n 都有 num1[i] == nums2[i] ,那么我们称 nums1 等于 nums2 。
42+
请你返回使 nums1 等于 nums2 的 最少 操作数。如果没办法让它们相等,请你返回 -1 。
43+
提示:
44+
n == nums1.length == nums2.length
45+
2 <= n <= 10^5
46+
0 <= nums1[i], nums2[j] <= 10^9
47+
0 <= k <= 10^5
48+
49+
模拟,判断加和减的次数是否相等。
50+
注意 RE java.lang.ArithmeticException: / by zero
51+
*/
Lines changed: 80 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,80 @@
1+
import java.util.ArrayList;
2+
import java.util.List;
3+
import java.util.PriorityQueue;
4+
5+
public class Solution2542 {
6+
public long maxScore(int[] nums1, int[] nums2, int k) {
7+
int n = nums1.length;
8+
List<Node> list = new ArrayList<>();
9+
for (int i = 0; i < n; i++) {
10+
list.add(new Node(i, nums1[i], nums2[i]));
11+
}
12+
// 大到小排序,枚举 min(nums2[i]) 范围 [k-1, n-1]
13+
list.sort((o1, o2) -> Integer.compare(o2.n2, o1.n2));
14+
15+
// 大小为 k 的最小堆
16+
PriorityQueue<Integer> minHeap = new PriorityQueue<>();
17+
long sum = 0;
18+
// [0, k-1]
19+
for (int i = 0; i < k; i++) {
20+
int n1 = list.get(i).n1;
21+
minHeap.add(n1);
22+
sum += n1;
23+
}
24+
long min = list.get(k - 1).n2;
25+
long res = sum * min;
26+
27+
// [k, n-1]
28+
for (int i = k; i < n; i++) {
29+
int n1 = list.get(i).n1;
30+
min = list.get(i).n2;
31+
32+
int top = minHeap.element();
33+
if (n1 > top) {
34+
minHeap.add(n1);
35+
sum -= minHeap.remove();
36+
sum += n1;
37+
}
38+
res = Math.max(res, sum * min);
39+
40+
}
41+
return res;
42+
}
43+
44+
private static class Node {
45+
int id;
46+
int n1;
47+
int n2;
48+
49+
public Node(int id, int n1, int n2) {
50+
this.id = id;
51+
this.n1 = n1;
52+
this.n2 = n2;
53+
}
54+
}
55+
}
56+
/*
57+
2542. 最大子序列的分数
58+
https://leetcode.cn/problems/maximum-subsequence-score/
59+
60+
第 96 场双周赛 T3。
61+
62+
给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,两者长度都是 n ,再给你一个正整数 k 。你必须从 nums1 中选一个长度为 k 的 子序列 对应的下标。
63+
对于选择的下标 i0 ,i1 ,..., ik - 1 ,你的 分数 定义如下:
64+
- nums1 中下标对应元素求和,乘以 nums2 中下标对应元素的 最小值 。
65+
- 用公示表示: (nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] , nums2[i1], ... ,nums2[ik - 1]) 。
66+
请你返回 最大 可能的分数。
67+
一个数组的 子序列 下标是集合 {0, 1, ..., n-1} 中删除若干元素得到的剩余集合,也可以不删除任何元素。
68+
提示:
69+
n == nums1.length == nums2.length
70+
1 <= n <= 10^5
71+
0 <= nums1[i], nums2[j] <= 10^5
72+
1 <= k <= n
73+
74+
将 nums1 和 nums2 组合起来后按 nums2 由大至小排序。枚举 nums2[i] 取值范围为 [k-1, n-1]
75+
同时用最小堆维护 k 个 nums1 最大值。
76+
时间复杂度 O(nlogn)
77+
空间复杂度 O(n)
78+
相似题目: 703. 数据流中的第 K 大元素
79+
https://leetcode.cn/problems/kth-largest-element-in-a-stream/
80+
*/
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
public class Solution2543 {
2+
public boolean isReachable(int targetX, int targetY) {
3+
int gcd = getGCD(targetX, targetY);
4+
// 是否为 2 的幂
5+
return (gcd & (gcd - 1)) == 0;
6+
}
7+
8+
private int getGCD(int num1, int num2) {
9+
if (num1 == 0) {
10+
return num2;
11+
}
12+
return getGCD(num2 % num1, num1);
13+
}
14+
}
15+
/*
16+
2543. 判断一个点是否可以到达
17+
https://leetcode.cn/problems/check-if-point-is-reachable/
18+
19+
第 96 场双周赛 T4。
20+
21+
给你一个无穷大的网格图。一开始你在 (1, 1) ,你需要通过有限步移动到达点 (targetX, targetY) 。
22+
每一步 ,你可以从点 (x, y) 移动到以下点之一:
23+
- (x, y - x)
24+
- (x - y, y)
25+
- (2 * x, y)
26+
- (x, 2 * y)
27+
给你两个整数 targetX 和 targetY ,分别表示你最后需要到达点的 X 和 Y 坐标。如果你可以从 (1, 1) 出发到达这个点,请你返回true ,否则返回 false 。
28+
提示:
29+
1 <= targetX, targetY <= 10^9
30+
31+
数学
32+
前两个操作是辗转相除法,即 GCD。
33+
后两个移动让 GCD 乘以 2^k.
34+
时间复杂度 O(logmin(targetX, targetY))
35+
空间复杂度 O(1)
36+
*/
Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,27 @@
1+
public class Solution2544 {
2+
public int alternateDigitSum(int n) {
3+
boolean positive = true;
4+
int res = 0;
5+
while (n > 0) {
6+
res += (positive ? 1 : -1) * (n % 10);
7+
n /= 10;
8+
positive = !positive;
9+
}
10+
return positive ? -res : res;
11+
}
12+
}
13+
/*
14+
2544. 交替数字和
15+
https://leetcode.cn/problems/alternating-digit-sum/
16+
17+
第 329 场周赛 T1。
18+
19+
给你一个正整数 n 。n 中的每一位数字都会按下述规则分配一个符号:
20+
- 最高有效位 上的数字分配到 正 号。
21+
- 剩余每位上数字的符号都与其相邻数字相反。
22+
返回所有数字及其对应符号的和。
23+
提示:
24+
1 <= n <= 10^9
25+
26+
模拟
27+
*/
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
import java.util.Arrays;
2+
3+
public class Solution2545 {
4+
public int[][] sortTheStudents(int[][] score, int k) {
5+
Arrays.sort(score, (o1, o2) -> Integer.compare(o2[k], o1[k]));
6+
return score;
7+
}
8+
}
9+
/*
10+
2545. 根据第 K 场考试的分数排序
11+
https://leetcode.cn/problems/sort-the-students-by-their-kth-score/
12+
13+
第 329 场周赛 T2。
14+
15+
班里有 m 位学生,共计划组织 n 场考试。给你一个下标从 0 开始、大小为 m x n 的整数矩阵 score ,
16+
其中每一行对应一位学生,而 score[i][j] 表示第 i 位学生在第 j 场考试取得的分数。矩阵 score 包含的整数 互不相同 。
17+
另给你一个整数 k 。请你按第 k 场考试分数从高到低完成对这些学生(矩阵中的行)的排序。
18+
返回排序后的矩阵。
19+
提示:
20+
m == score.length
21+
n == score[i].length
22+
1 <= m, n <= 250
23+
1 <= score[i][j] <= 10^5
24+
score 由 不同 的整数组成
25+
0 <= k < n
26+
27+
模拟/库函数
28+
时间复杂度:库函数不讨论时间复杂度。
29+
*/
Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
public class Solution2546 {
2+
public boolean makeStringsEqual(String s, String target) {
3+
if (s.equals(target)) {
4+
return true;
5+
}
6+
int n = s.length();
7+
int s0 = 0;
8+
for (char ch : s.toCharArray()) {
9+
if (ch == '0') {
10+
s0++;
11+
}
12+
}
13+
int t0 = 0;
14+
for (char ch : target.toCharArray()) {
15+
if (ch == '0') {
16+
t0++;
17+
}
18+
}
19+
return s0 != n && t0 != n;
20+
}
21+
}
22+
/*
23+
2546. 执行逐位运算使字符串相等
24+
https://leetcode.cn/problems/apply-bitwise-operations-to-make-strings-equal/
25+
26+
第 329 场周赛 T3。
27+
28+
给你两个下标从 0 开始的 二元 字符串 s 和 target ,两个字符串的长度均为 n 。你可以对 s 执行下述操作 任意 次:
29+
- 选择两个 不同 的下标 i 和 j ,其中 0 <= i, j < n 。
30+
- 同时,将 s[i] 替换为 (s[i] OR s[j]) ,s[j] 替换为 (s[i] XOR s[j]) 。
31+
例如,如果 s = "0110" ,你可以选择 i = 0 和 j = 2,然后同时将 s[0] 替换为 (s[0] OR s[2] = 0 OR 1 = 1),并将 s[2] 替换为 (s[0] XOR s[2] = 0 XOR 1 = 1),最终得到 s = "1110" 。
32+
如果可以使 s 等于 target ,返回 true ,否则,返回 false 。
33+
提示:
34+
n == s.length == target.length
35+
2 <= n <= 10^5
36+
s 和 target 仅由数字 0 和 1 组成
37+
38+
找规律
39+
i,j -> i|j, i^j
40+
0,0 -> 0,0
41+
0,1 -> 1,1
42+
1,0 -> 1,1
43+
1,1 -> 1,0
44+
可以观察到 1 不能凭空出现,不能突然消失。
45+
如果数组本身没 1,将不可能出现 1;
46+
如果数组本身有 1,不可能全部变成 0;
47+
因此当两数组不相等时,其中任一数组不能为全 0 数组
48+
*/
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 Solution2540Tests {
5+
private final Solution2540 solution2540 = new Solution2540();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums1 = {1, 2, 3};
10+
int[] nums2 = {2, 4};
11+
int expected = 2;
12+
Assertions.assertEquals(expected, solution2540.getCommon(nums1, nums2));
13+
}
14+
15+
@Test
16+
public void example2() {
17+
int[] nums1 = {1, 2, 3, 6};
18+
int[] nums2 = {2, 3, 4, 5};
19+
int expected = 2;
20+
Assertions.assertEquals(expected, solution2540.getCommon(nums1, nums2));
21+
}
22+
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
import org.junit.jupiter.api.Assertions;
2+
import org.junit.jupiter.api.Test;
3+
4+
public class Solution2541Tests {
5+
private final Solution2541 solution2541 = new Solution2541();
6+
7+
@Test
8+
public void example1() {
9+
int[] nums1 = {4, 3, 1, 4};
10+
int[] nums2 = {1, 3, 7, 1};
11+
int k = 3;
12+
long expected = 2;
13+
Assertions.assertEquals(expected, solution2541.minOperations(nums1, nums2, k));
14+
}
15+
16+
@Test
17+
public void example2() {
18+
int[] nums1 = {3, 8, 5, 2};
19+
int[] nums2 = {2, 4, 1, 6};
20+
int k = 1;
21+
long expected = -1;
22+
Assertions.assertEquals(expected, solution2541.minOperations(nums1, nums2, k));
23+
}
24+
25+
// 补充用例
26+
@Test
27+
public void example3() {
28+
// https://leetcode.cn/submissions/detail/397340535/
29+
// RE java.lang.ArithmeticException: / by zero
30+
int[] nums1 = {10, 5, 15, 20};
31+
int[] nums2 = {20, 10, 15, 5};
32+
int k = 0;
33+
long expected = -1;
34+
Assertions.assertEquals(expected, solution2541.minOperations(nums1, nums2, k));
35+
}
36+
}

0 commit comments

Comments
 (0)