脑子不清醒的一场
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]] 输出:[[1,6],[3,9],[4,5]] 解释: value = 1 的物品在 items1 中 weight = 1 ,在 items2 中 weight = 5 ,总重量为 1 + 5 = 6 。 value = 3 的物品再 items1 中 weight = 8 ,在 items2 中 weight = 1 ,总重量为 8 + 1 = 9 。 value = 4 的物品在 items1 中 weight = 5 ,总重量为 5 。 所以,我们返回 [[1,6],[3,9],[4,5]] 。
示例 2:
输入:items1 = [[1,1],[3,2],[2,3]], items2 = [[2,1],[3,2],[1,3]] 输出:[[1,4],[2,4],[3,4]] 解释: value = 1 的物品在 items1 中 weight = 1 ,在 items2 中 weight = 3 ,总重量为 1 + 3 = 4 。 value = 2 的物品在 items1 中 weight = 3 ,在 items2 中 weight = 1 ,总重量为 3 + 1 = 4 。 value = 3 的物品在 items1 中 weight = 2 ,在 items2 中 weight = 2 ,总重量为 2 + 2 = 4 。 所以,我们返回 [[1,4],[2,4],[3,4]] 。
示例 3:
输入:items1 = [[1,3],[2,2]], items2 = [[7,1],[2,2],[1,4]] 输出:[[1,7],[2,4],[7,1]] 解释: value = 1 的物品在 items1 中 weight = 3 ,在 items2 中 weight = 4 ,总重量为 3 + 4 = 7 。 value = 2 的物品在 items1 中 weight = 2 ,在 items2 中 weight = 2 ,总重量为 2 + 2 = 4 。 value = 7 的物品在 items2 中 weight = 1 ,总重量为 1 。 所以,我们返回 [[1,7],[2,4],[7,1]] 。
提示:
- 1 <= items1.length, items2.length <= 1000
- items1[i].length == items2[i].length == 2
- 1 <= valuei, weighti <= 1000
- items1 中每个 valuei 都是 唯一的 。
- items2 中每个 valuei 都是 唯一的 。
思路:
可以用双指针来做
class Solution {
public List<List<Integer>> mergeSimilarItems(int[][] a, int[][] b) {
int i = 0, j = 0;
int n = a.length, m = b.length;
Arrays.sort(a, (o1, o2) -> (o1[0] - o2[0]));
Arrays.sort(b, (o1, o2) -> (o1[0] - o2[0]));
List<List<Integer>> list = new ArrayList<>();
while (i < n && j < m) {
List<Integer> t = new ArrayList<>();
if (a[i][0] != b[j][0]) {
if (a[i][0] < b[j][0]) {
t.add(a[i][0]);
t.add(a[i][1]);
i++;
} else {
t.add(b[j][0]);
t.add(b[j][1]);
j++;
}
} else {
t.add(a[i][0]);
t.add(a[i][1] + b[j][1]);
i++;
j++;
}
list.add(t);
}
while (i < n) {
List<Integer> t = new ArrayList<>();
t.add(a[i][0]);
t.add(a[i][1]);
i++;
list.add(t);
}
while (j < m) {
List<Integer> t = new ArrayList<>();
t.add(b[j][0]);
t.add(b[j][1]);
j++;
list.add(t);
}
return list;
}
}
太难调了,还是用哈希表简单
class Solution {
public List<List<Integer>> mergeSimilarItems(int[][] a, int[][] b) {
Map<Integer, Integer> map = new HashMap<>();
for (int[] p : a) {
map.merge(p[0], p[1], Integer::sum);
}
for (int[] p : b) {
map.merge(p[0], p[1], Integer::sum);
}
List<List<Integer>> res = new ArrayList<>();
for (int x : map.keySet()) {
int y = map.get(x);
List<Integer> t = new ArrayList<>();
t.add(x);
t.add(y);
res.add(t);
}
Collections.sort(res, (o1, o2) -> (o1.get(0) - o2.get(0)));
return res;
}
}
6142. 统计坏数对的数目
给你一个下标从 0 开始的整数数组 nums 。如果 i < j 且 j - i != nums[j] - nums[i] ,那么我们称 (i, j) 是一个 坏数对 。
请你返回 nums 中 坏数对 的总数目。
示例 1:
输入:nums = [4,1,3,3] 输出:5 解释:数对 (0, 1) 是坏数对,因为 1 - 0 != 1 - 4 。 数对 (0, 2) 是坏数对,因为 2 - 0 != 3 - 4, 2 != -1 。 数对 (0, 3) 是坏数对,因为 3 - 0 != 3 - 4, 3 != -1 。 数对 (1, 2) 是坏数对,因为 2 - 1 != 3 - 1, 1 != 2 。 数对 (2, 3) 是坏数对,因为 3 - 2 != 3 - 3, 1 != 0 。 总共有 5 个坏数对,所以我们返回 5 。
示例 2:
输入:nums = [1,2,3,4,5] 输出:0 解释:没有坏数对。
提示:
- 1 <= nums.length <= 105
- 1 <= nums[i] <= 109
思路:
变换一下式子得j - nums[j] == i - nums[i]
即统计所有x - nums[x]
相同的数对的个数
class Solution {
public long countBadPairs(int[] nums) {
Map<Integer, Integer> map = new HashMap<>();
long c = 0;
for (int i = 0; i < nums.length; i++) {
int x = i - nums[i];
c += i - map.getOrDefault(x, 0);
map.merge(x, 1, Integer::sum);
}
return c;
}
}
6174. 任务调度器 II
- 通过的用户数1955
- 尝试过的用户数2467
- 用户总通过次数2014
- 用户总提交次数5120
- 题目难度Medium
给你一个下标从 0 开始的正整数数组 tasks ,表示需要 按顺序 完成的任务,其中 tasks[i] 表示第 i 件任务的 类型 。
同时给你一个正整数 space ,表示一个任务完成 后 ,另一个 相同 类型任务完成前需要间隔的 最少 天数。
在所有任务完成前的每一天,你都必须进行以下两种操作中的一种:
- 完成 tasks 中的下一个任务
- 休息一天
请你返回完成所有任务所需的 最少 天数。
示例 1:
输入:tasks = [1,2,1,2,3,1], space = 3 输出:9 解释: 9 天完成所有任务的一种方法是: 第 1 天:完成任务 0 。 第 2 天:完成任务 1 。 第 3 天:休息。 第 4 天:休息。 第 5 天:完成任务 2 。 第 6 天:完成任务 3 。 第 7 天:休息。 第 8 天:完成任务 4 。 第 9 天:完成任务 5 。 可以证明无法少于 9 天完成所有任务。
示例 2:
输入:tasks = [5,8,8,5], space = 2 输出:6 解释: 6 天完成所有任务的一种方法是: 第 1 天:完成任务 0 。 第 2 天:完成任务 1 。 第 3 天:休息。 第 4 天:休息。 第 5 天:完成任务 2 。 第 6 天:完成任务 3 。 可以证明无法少于 6 天完成所有任务。
提示:
- 1 <= tasks.length <= 105
- 1 <= tasks[i] <= 109
- 1 <= space <= tasks.length
思路:
贪心
class Solution {
public long taskSchedulerII(int[] tasks, int s) {
Map<Integer, Long> map = new HashMap<>();
long cur = 0;
for (int i = 0; i < tasks.length; i++) {
long pre = map.getOrDefault(tasks[i], -1000000L);
cur = Math.max(cur + 1, pre + s + 1);
map.put(tasks[i], cur);
}
return cur;
}
}
6144. 将数组排序的最少替换次数
- 通过的用户数840
- 尝试过的用户数1467
- 用户总通过次数934
- 用户总提交次数3650
- 题目难度Hard
给你一个下表从 0 开始的整数数组 nums 。每次操作中,你可以将数组中任何一个元素替换为 任意两个 和为该元素的数字。
- 比方说,nums = [5,6,7] 。一次操作中,我们可以将 nums[1] 替换成 2 和 4 ,将 nums 转变成 [5,2,4,7] 。
请你执行上述操作,将数组变成元素按 非递减 顺序排列的数组,并返回所需的最少操作次数。
示例 1:
输入:nums = [3,9,3] 输出:2 解释:以下是将数组变成非递减顺序的步骤: - [3,9,3] ,将9 变成 3 和 6 ,得到数组 [3,3,6,3] - [3,3,6,3] ,将 6 变成 3 和 3 ,得到数组 [3,3,3,3,3] 总共需要 2 步将数组变成非递减有序,所以我们返回 2 。
示例 2:
输入:nums = [1,2,3,4,5] 输出:0 解释:数组已经是非递减顺序,所以我们返回 0 。
提示:
- 1 <= nums.length <= 105
- 1 <= nums[i] <= 109
思路:
贪心 + 二分
class Solution {
public long minimumReplacement(int[] nums) {
int n = nums.length;
long res = 0;
int pre = nums[n - 1];
for (int i = n - 2; i >= 0; i--) {
if (nums[i] <= pre) {
pre = nums[i];
continue;
}
int l = 1, r = nums[i];
while (l < r) {
int mid = l + r >> 1;
if (1.0 * nums[i] / mid <= pre)
r = mid;
else
l = mid + 1;
}
res += l - 1;
pre = nums[i] / l;
}
return res;
}
}