持续创作,加速成长!这是我参与「掘金日新计划 · 6 月更文挑战」的第29天,点击查看活动详情
刷题的日常
一天一题,保持脑子清爽
替换数组中的元素
来自leetcode的2295题,题意如下:
给你一个下标从 0开始的数组nums,它包含 n个 互不相同的正整数。请你对这个数组执行 m个操作,在第 i个操作中,你需要将数字operations[i][0] 替换成operations[i][1]。
题目保证在第 i个操作中:
- operations[i][0]在nums中存在。
- operations[i][1]在nums中不存在。
请你返回执行完所有操作后的数组。 数据量如下:
- n == nums.length
- m == operations.length
- 1 <= n, m <= 105
- nums中所有数字 互不相同。
- operations[i].length == 2
- 1 <= nums[i], operations[i][0], operations[i][1] <= 106
- 在执行第i 个操作时,operations[i][0]在nums中存在。
- 在执行第i个操作时,operations[i][1]在nums中不存在。
理解题意
题意很简单,其实就不需要怎么提取了。我们需要用operations中的第一个数,去替换原数组中的和operations的第0的数相同的数。
做题思路
第一想法肯定是直接暴力解,循环operations数组,对每个操作都进行替换,最终返回就行。
然而,题目给出的数据量会导致超时,所以需要优化以下。
从题目给出的条件中,我们可以发现,每次替换的数都是之前没有出现过的,那么,我们就可以用Hash表来保存映射关系,最终只替换一次就可以了,过程如下:
- 遍历operations列表
- 将映射关系记录起来
- 这里需要注意的是,以前的数也有可能被覆盖
- 我们需要再开辟Hash表来保存覆盖过的数
- 通过遍历nums数组,将Hash表中匹配的数替换掉就可以了
代码实现
循环为2次,时间复杂度为O(n * m),代码如下:
public class Solution {
public int[] arrayChange(int[] nums, int[][] operations) {
Map<Integer, Integer> replaceMap = new HashMap<>();
Map<Integer, Integer> replaceMapRe = new HashMap<>();
for (int[] operation : operations) {
if (replaceMapRe.containsKey(operation[0])) {
replaceMap.put(replaceMapRe.get(operation[0]), operation[1]);
replaceMapRe.put(operation[1], replaceMapRe.get(operation[0]));
continue;
}
replaceMap.put(operation[0], operation[1]);
replaceMapRe.put(operation[1], operation[0]);
}
for (int i = 0; i < nums.length; i++) {
Integer replace = replaceMap.get(nums[i]);
nums[i] = replace == null ? nums[i] : replace;
}
return nums;
}
}