leetcode biweekly conttest 84
最近越来越没有时间参加周赛了,只能赛后来写题解了。第二题稍微有点意思,其余的题目确实没有多少亮点。最近有亮点的题目确实越来越少了。
6141. 合并相似的物品
题目
给你两个二维整数数组 items1
和 items2
,表示两个物品集合。每个数组 items
有以下特质:
items[i] = [valuei, weighti]
其中valuei
表示第i
件物品的 价值 ,weighti
表示第i
件物品的 重量 。items
中每件物品的价值都是 唯一的 。
请你返回一个二维数组ret
,其中ret[i] = [valuei, weighti]
,weighti
是所有价值为valuei
物品的 重量之和 。
注意:ret
应该按价值 升序 排序后返回。
示例 1:
输入:items1 = [[1,1],[4,5],[3,8]], items2 = [[3,1],[1,5]] |
示例 2:
输入:items1 = [[1,1],[3,2],[2,3]], items2 = [[2,1],[3,2],[1,3]] |
示例 3:
输入:items1 = [[1,3],[2,2]], items2 = [[7,1],[2,2],[1,4]] |
提示:
1 <= items1.length, items2.length <= 1000
items1[i].length == items2[i].length == 2
1 <= valuei, weighti <= 1000
items1
中每个valuei
都是 唯一的 。items2
中每个valuei
都是 唯一的 。
地址
https://leetcode.cn/problems/merge-similar-items/
题意
直接遍历 + 哈希表
思路
- 简单题目,直接哈希表合并即可,或者直接遍历即可。
- 复杂度分析:
- 时间复杂度:$O(n \log n)$,其中 $n$ 为数组的长度。
- 空间复杂度:$O(n)$,其中 $n$ 为数组的长度。
代码
class Solution { |
6142. 统计坏数对的数目
题目
给你一个下标从 0
开始的整数数组 nums
。如果 i < j
且 j - i != nums[j] - nums[i]
,那么我们称 (i, j)
是一个 坏数对 。
请你返回 nums
中 坏数对 的总数目。
示例 1:
输入:nums = [4,1,3,3] |
示例 2:
输入:nums = [1,2,3,4,5] |
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 109
地址
https://leetcode.cn/problems/count-number-of-bad-pairs/
题意
数学
思路
- 题目要求 $j - i \neq nums[j] - nums[i]$, 该不等式可以转换为 $nums[i] - i \neq nums[j] - j$,我们因此可以找到不是坏的数对的数目 $tot$,总的数对数目为 $\dfrac{n \times (n - 1)}{2}$,则可以知道坏的数对的数目为 $\dfrac{n \times (n - 1)}{2} - tot$。我们可以用哈希表统计每个元素 $x = nums[i] - i$ 的出现次数。
- 可能更复杂的解法还有线段树之类的解法。
- 复杂度分析:
- 时间复杂度:时间复杂度为 $O(n)$,$n$ 表示数组的长度。
- 空间复杂度:$O(n)$,$n$ 表示数组的长度。
代码
class Solution { |
6174. 任务调度器 II
题目
给你一个下标从 0
开始的正整数数组 tasks
,表示需要 按顺序 完成的任务,其中 tasks[i]
表示第 i
件任务的 类型 。
同时给你一个正整数 space
,表示一个任务完成 后 ,另一个 相同 类型任务完成前需要间隔的 最少 天数。
在所有任务完成前的每一天,你都必须进行以下两种操作中的一种:
- 完成
tasks
中的下一个任务 - 休息一天
请你返回完成所有任务所需的 最少 天数。
示例 1:
输入:tasks = [1,2,1,2,3,1], space = 3 |
示例 2:
输入:tasks = [5,8,8,5], space = 2 |
提示:
1 <= tasks.length <= 105
1 <= tasks[i] <= 109
1 <= space <= tasks.length
地址
https://leetcode.cn/problems/task-scheduler-ii/
题意
模拟 + 哈希表
思路
- 感觉这个题目出的挺无聊,直接模拟即可,我们设哈希表 $prev$,其中 $prev[x]$ 表示任务 $x$ 最后一次发生的时间。我们遍历每个任务 $task[i]$,有以下两种情况需要处理,设上一个任务的完成时间为 $now$:
- 如果当前的任务 $task[i]$ 之前没有出现过,则此时当前任务的完成时间肯定为 $now + 1$,且此时 $prev[task[i]] = now + 1$,且此时更新 $now = now + 1$;
- 如果当前的任务 $task[i]$ 之前出现过,由于相同的任务的间隔必须大于 $space$, 因此当前任务的完成时间要么是 $now + 1$ 和 $prev[task[i]] + space + 1$ 之间的较大值,则此时 $now = \max(now + 1,prev[task[i]] + space + 1) $, 更新 $prev[task[i]] = now$;
- 复杂度分析:
- 时间复杂度:时间复杂度为 $O(n)$,其中 $n$ 表示数组的长度。
- 空间复杂度:空间复杂度为 $O(n)$,其中 $n$ 表示数组的长度。
代码
class Solution { |
6144. 将数组排序的最少替换次数
题目
给你一个下表从 0
开始的整数数组 nums
。每次操作中,你可以将数组中任何一个元素替换为 任意两个 和为该元素的数字。
比方说,nums = [5,6,7]
。一次操作中,我们可以将 nums[1]
替换成 2
和 4
,将 nums
转变成 [5,2,4,7]
。
请你执行上述操作,将数组变成元素按 非递减 顺序排列的数组,并返回所需的最少操作次数。
示例 1:
输入:nums = [3,9,3] |
示例 2:
输入:nums = [1,2,3,4,5] |
提示:
1 <= nums.length <= 105
1 <= nums[i] <= 109
地址
https://leetcode.cn/problems/minimum-replacements-to-sort-the-array/
题意
贪心算法
思路
- 首先我们为了减少替换次数,此时我们应当保证最后面的数尽可能的大,才能保证前面的数尽可能的不被替换。因此我们从后往前遍历数组,对于第 $i$ 个元素,如果出现 $nums[i] > nums[i + 1]$,此时我们应该进行拆分,但在拆分时需要的技巧是需要满足两个条件:
- 拆分的出数的序列中的最大值一定要满足小于等于 $nums[i+1]$;
- 拆分的出数的序列中的最小值一定要尽可能的大;
如何满足以上条件的拆分法,所有需要切分的最少次数 $k = \dfrac{nums[i]}{nums[i+1]}$。此时可以知道切分后最小的数为 $x = \lfloor\dfrac{nums[i]}{k + 1} \rfloor$。
- 复杂度分析:
- 时间复杂度:$O(n)$,$n$ 表示数组的长度。
- 空间复杂度:$O(1)$。
代码
class Solution { |
欢迎关注和打赏,感谢支持!
- 关注我的博客: http://mikemeng.org/
- 关注我的知乎:https://www.zhihu.com/people/da-hua-niu
- 关注我的微信公众号: 公务程序猿
扫描二维码,分享此文章