首先祝大家兔年快乐!

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;
    }
}

数据题过多。我觉得是出题出的很差的一个双周赛。

Leave a Reply

Your email address will not be published. Required fields are marked *