首先祝大家兔年快乐!
6300. Minimum Common Value
给你两个整数数组 nums1 和 nums2 ,它们已经按非降序排序,请你返回两个数组的 最小公共整数 。如果两个数组 nums1 和 nums2 没有公共整数,请你返回 -1 。
如果一个整数在两个数组中都 至少出现一次 ,那么这个整数是数组 nums1 和 nums2 公共 的。
测试样例
输入:nums1 = [1,2,3], nums2 = [2,4]
输出:2
解释:
两个数组的最小公共元素是 2 ,所以我们返回 2 。
解答:暴力枚举
class Solution {
public int getCommon(int[] nums1, int[] nums2) {
Set<Integer> set = new HashSet<>();
for (int i : nums1) {
set.add(i);
}
for (int i : nums2) {
if (set.contains(i)) {
return i;
}
}
return -1;
}
}
6275. Minimum Operations to Make Array Equal II
给你两个整数数组 nums1 和 nums2 ,两个数组长度都是 n ,再给你一个整数 k 。你可以对数组 nums1 进行以下操作:
- 选择两个下标 i 和 j ,将 nums1[i] 增加 k ,将 nums1[j] 减少 k 。换言之,nums1[i] = nums1[i] + k 且 nums1[j] = nums1[j] - k 。
如果对于所有满足 0 <= i < n 都有 num1[i] == nums2[i] ,那么我们称 nums1 等于 nums2 。请你返回使 nums1 等于 nums2 的 最少 操作数。如果没办法让它们相等,请你返回 -1 。
测试样例:
输入:nums1 = [4,3,1,4], nums2 = [1,3,7,1], k = 3
输出:2
解释:
我们可以通过 2 个操作将 nums1 变成 nums2 。
第 1 个操作:i = 2 ,j = 0 。操作后得到 nums1 = [1,3,4,4] 。
第 2 个操作:i = 2 ,j = 3 。操作后得到 nums1 = [1,3,7,1] 。
无法用更少操作使两个数组相等。
解答: 差值的比较。注意k=2的情况
class Solution {
public long minOperations(int[] nums1, int[] nums2, int k) {
int len = nums1.length;
long sum = 0, posSum = 0;
for (int i = 0; i < len; ++i) {
int diff = nums1[i] - nums2[i];
if (k != 0 && Math.abs(diff) % k != 0) {
return -1;
}
sum += diff;
if (diff > 0) {
posSum += diff;
}
}
if (sum != 0) {
return -1;
}
if (k == 0) {
return posSum == 0 ? 0 : -1;
}
return posSum / k;
}
}
6302. Maximum Subsequence Score
给你两个下标从 0 开始的整数数组 nums1 和 nums2 ,两者长度都是 n ,再给你一个正整数 k 。你必须从 nums1 中选一个长度为 k 的 子序列 对应的下标。
对于选择的下标 i0 ,i1 ,..., ik - 1 ,你的 分数 定义如下:
nums1 中下标对应元素求和,乘以 nums2 中下标对应元素的 最小值 。
用公示表示: (nums1[i0] + nums1[i1] +...+ nums1[ik - 1]) * min(nums2[i0] , nums2[i1], ... ,nums2[ik - 1]) 。
请你返回 最大 可能的分数。一个数组的 子序列 下标是集合 {0, 1, ..., n-1} 中删除若干元素得到的剩余集合,也可以不删除任何元素。
测试样例
输入:nums1 = [1,3,3,2], nums2 = [2,1,3,4], k = 3
输出:12
解答:首先将nums2从大到小排序。然后利用优先队列计算当前倍率下,最大可到达的sum
class Solution {
public long maxScore(int[] nums1, int[] nums2, int k) {
int len = nums1.length;
Integer[] sort = new Integer[len];
for (int i = 0; i < len; ++i) {
sort[i] = i;
}
Arrays.sort(sort, (a, b) -> (nums2[b] - nums2[a]));
PriorityQueue<Integer> queue = new PriorityQueue<>();
long sum = 0, max = 0;
for (int i = 0; i < len; ++i) {
int index = sort[i];
queue.add(nums1[index]);
sum += nums1[index];
if (queue.size() > k) {
sum -= queue.poll();
}
int cur = nums2[index];
if (queue.size() == k) {
max = Math.max(max, sum * cur);
}
}
return max;
}
}
6301. 判断一个点是否可以到达
给你一个无穷大的网格图。一开始你在 (1, 1) ,你需要通过有限步移动到达点 (targetX, targetY) 。
每一步 ,你可以从点 (x, y) 移动到以下点之一:
- (x, y - x)
- (x - y, y)
- (2 * x, y)
- (x, 2 * y)
给你两个整数 targetX 和 targetY ,分别表示你最后需要到达点的 X 和 Y 坐标。如果你可以从 (1, 1) 出发到达这个点,请你返回true ,否则返回 false 。测试样例
输入:targetX = 6, targetY = 9
输出:false
解答:周赛的时候没想道最大公因数。其实按照题目的意思,前2种计算是不会影响到x和y最大公因数的(计算最大公因数用到取模,所以减法不影响最大公因数)。后2种,最多只会让最大公因数乘以2。加之初始是(1,1)开始,所以当前2数的最大公因数必为2^n。
class Solution {
public boolean isReachable(int targetX, int targetY) {
int diff = Math.abs(targetX - targetY);
if (diff == 0) {
return isBinary(targetX);
} else {
return (targetX + targetY - 2) % diff == 0;
}
}
private boolean isBinary(int n) {
while (n > 1) {
if (n % 2 == 1) {
return false;
}
n /= 2;
}
return n == 1;
}
}
数据题过多。我觉得是出题出的很差的一个双周赛。