基本解法
- 排序:将元素从小到大排序,索引对应元素不符就是所求元素。具体解法有:
- Arrays.Sort()
- 哈希表存储
- 映射:将每个索引和元素映射,最后没有映射或重复映射就是所求。具体解法有:
- 归位法,将每个元素都归位到对应的索引,重复归位的元素就是所求
- 置负数,将访问元素对应索引的元素置负,表示该索引被对应,最后为正的元素的对应索引即是所求(见举例)
- 异或:基于a^a=0,a^0=a的性质,将索引和元素同时异或,最后留下的就是重复或缺失元素。
题目举例
leetcode 645 错误的集合
集合 S 包含从1到 n 的整数。不幸的是,因为数据错误,导致集合里面某一个元素复制了成了集合里面的另外一个元素的值,导致集合丢失了一个整数并且有一个元素重复。
给定一个数组 nums 代表了集合 S 发生错误后的结果。你的任务是首先寻找到重复出现的整数,再找到丢失的整数,将它们以数组的形式返回。
示例 1:
输入: nums = [1,2,2,4]
输出: [2,3]
注意:
给定数组的长度范围是 [2, 10000]。
给定的数组是无序的。
代码实现
public int[] findErrorNums(int[] nums) {
int n = nums.length;
int dup = -1;
for (int i = 0; i < n; i++) {
int index = Math.abs(nums[i]) - 1;
if (nums[index] < 0) {
dup = Math.abs(nums[i]);
} else {
nums[index] *= -1;
}
}
int missing = -1;
for (int i = 0; i < n; i++) {
if (nums[i] > 0) {
//将索引+1变元素
missing = i + 1;
}
}
int[] ret = new int[2];
ret[0] = dup;
ret[1] = missing;
return ret;
}