
脑子不清醒的一场
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;elsel = mid + 1;}res += l - 1;pre = nums[i] / l;}return res;}}
