[LeetCode316周赛]
6224. 最大公因数等于 K 的子数组数目
https://leetcode.cn/contest/weekly-contest-316/problems/number-of-subarrays-with-gcd-equal-to-k/
给你一个整数数组 nums
和一个整数 k
,请你统计并返回 nums
的子数组中元素的最大公因数等于 k
的子数组数目。
子数组 是数组中一个连续的非空序列。
数组的最大公因数 是能整除数组中所有元素的最大整数。
输入:nums = [9,3,1,2,6,3], k = 3
输出:4
解释:nums 的子数组中,以 3 作为最大公因数的子数组如下(加粗字体):
- [9,3,1,2,6,3]
- [9,3,1,2,6,3]
- [9,3,1,2,6,3]
- [9,3,1,2,6,3]
Solution
枚举:
- 每次循环找以当前元素为起始且满足条件的子数组数量
注意一个点:0 和任何数 x 的最大公约数都是 x
class Solution {
public int gcd(int M, int N) {
int rem;
while (N > 0) {
rem = M % N;
M = N;
N = rem;
}
return M;
}
public int subarrayGCD(int[] nums, int k) {
int n = nums.length;
int ans = 0;
for (int i = 0; i < n; i++) {
if (nums[i] % k != 0) {
continue;
}
int g = 0;
for (int j = i; j < n; j++) {
g = gcd(g, nums[j]);
if (g == k) {
ans++;
}
}
}
return ans;
}
}
6216. 使数组相等的最小开销
https://leetcode.cn/contest/weekly-contest-316/problems/minimum-cost-to-make-array-equal/
给你两个下标从 0 开始的数组 nums
和 cost
,分别包含 n
个 正 整数。
你可以执行下面操作 任意 次:
将 nums
中 任意 元素增加或者减小 1 。
对第 i 个元素执行一次操作的开销是 cost[i]
。
请你返回使 nums
中所有元素 相等 的 最少 总开销。
输入:nums = [1,3,5,2], cost = [2,3,1,14]
输出:8
解释:我们可以执行以下操作使所有元素变为 2 :
- 增加第 0 个元素 1 次,开销为 2 。
- 减小第 1 个元素 1 次,开销为 3 。
- 减小第 2 个元素 3 次,开销为 1 + 1 + 1 = 3 。
总开销为 2 + 3 + 3 = 8 。
这是最小开销。
输入:nums = [2,2,2,2,2], cost = [4,2,8,1,3]
输出:0
解释:数组中所有元素已经全部相等,不需要执行额外的操作。
引例 462. 最小操作次数使数组元素相等 II
https://leetcode.cn/problems/minimum-moves-to-equal-array-elements-ii/
给你一个长度为 n
的整数数组 nums
,返回使所有数组元素相等需要的最小操作数。
在一次操作中,你可以使数组中的一个元素加 1 或者减 1 。
输入:nums = [1,2,3]
输出:2
解释:
只需要两次操作(每次操作指南使一个元素加 1 或减 1):
[1,2,3] => [2,2,3] => [2,2,2]
解题思路
抽象化为一个递增数列,选择一个数,使得所有数与该数的差的和最小。
==>
中位数!!!
没错,我们的目标值就是 中位数
!
class Solution {
public int minMoves2(int[] nums) {
Arrays.sort(nums);
int mid = nums[nums.length / 2];
int ans = 0;
for (int x : nums) {
ans += Math.abs(x - mid);
}
return ans;
}
}
Solution
该题和引例中的题类似,参考灵神的解法,只需要把 cost[i] 看作 nums[i] 出现的次数进行排列,然后按照上面的思路写就可以了。
引用灵神的代码,我自己写的 Java 版越界了:
class Solution:
def minCost(self, nums: List[int], cost: List[int]) -> int:
a = sorted(zip(nums, cost))
s, mid = 0, sum(cost) // 2
for x, c in a:
s += c
if s > mid: # 把所有数变成 x
return sum(abs(y - x) * c for y, c in a)