双周赛第84场
双周赛84
这次双周赛,其实我只做出来了第一题,下面这三道都是听了讲解才写出来。
2364 统计坏数对的数目
这道题给出条件:如果 i < j
并且j - i != nums[j] - nums[i]
,那么我们称(i, j)
是一个坏数对。
这里的式子两边都是两个字母,那这个规律直接用得话,去枚举需要n^2的时间复杂度,所以我们做一个变换,满足nums[j] - j != nums[i] - i
的(i,j)
是一个坏数对。那么这个时候,式子的一边只有一个字母,复杂度就降下来了。那么这时候就明了, 我们可以使用map存nums[i] - i
,然后求好数对的个数,用总的数对数相减就好。
typedef long long LL;
class Solution {
public:
LL C(int n){ // 求组合数
return n*(n-1ll)/2;
}
long long countBadPairs(vector<int>& nums) {
int n = nums.size();
LL res = C(n);
unordered_map<int,int> m;
for(int i = 0; i<n; i++) {
m[nums[i]-i]++;
}
// 学到了一个迭代map的方法。
for(auto&[k,v] : m) {
res -= C(v);
}
return res;
}
};
这道题主要就是学到了对式子做变换降低复杂度的技巧.
2365 任务调度器II
这道题其实是用贪心的思想写,一个任务,能做就做,越早做越好。
我们记录任务上一次是在哪天做的,然后判断需要等还是直接做。
typedef long long LL;
class Solution {
public:
long long taskSchedulerII(vector<int>& tasks, int space) {
LL res =0; // 最后返回的天数
unordered_map<LL,LL> m;
int n = tasks.size();
for(auto a : tasks) {
res = max(res+1,m[a]); // 满足两个条件,比前一天+1,与上一次任务间隔space天
m[a] = res + space+1;
}
return res;
}
};
2366 将数组排序的最少替换次数
给你一个下表从 0 开始的整数数组 nums 。每次操作中,你可以将数组中任何一个元素替换为 任意两个 和为该元素的数字。
比方说,nums = [5,6,7] 。一次操作中,我们可以将 nums[1] 替换成 2 和 4 ,将 nums 转变成 [5,2,4,7] 。
请你执行上述操作,将数组变成元素按 非递减 顺序排列的数组,并返回所需的最少操作次数。
来源:力扣(LeetCode)
链接:https://leetcode.cn/problems/minimum-replacements-to-sort-the-array
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
这道题也是贪心的一个做法,现在a和b挨着,b在a后面,那么我们就要考虑让a分割为比b小的数,并且分割出来的数还要非降序排列。我们假设分割成了k个数,a1 + a2 + a3 +... + ak = a,这时候要想同两点:
-
a分割出来的数越大越好,这样的话,a1前面的数就好划分了,就可以划分更少次
-
k越小越好,让分割次数变少嘛。
这两点统一起来,我们就得到个什么呢,那就是让a均分为k个,然后,怎么确定最小的k呢,我们用 a/b向上取整,就能确定k(分割出出来的数大,k还小).这样分解出来的数都比b小,如果a/k 有余数为r,那么就在后r个数每个数加1就行了。
下面的代码用到了一个技巧:求a/b向上取整,等于 a+b-1 /b 向下取整.
typedef long long LL;
class Solution {
public:
long long minimumReplacement(vector<int>& nums) {
LL res = 0;
int n = nums.size();
for(int i = n-2,last = nums.back();i>=0;i--) { // 最后一个不用动 ,last表示上一次处理找到的最小的数。
if(nums[i]<=last) { // 当这个数比上次的小时,不用分割,改下last就行了。
last = nums[i];
}else {
int k = (nums[i] + last - 1)/last; //a/b向上取整,等于 a+b-1 /b 向下取整
res += k-1; // 分出来k份,等于就是分了k-1次。
last = nums[i]/k;
}
}
return res;
}
};