leetcode448. 找到所有数组中消失的数字
我的解法:额外数组
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
int n = nums.length;
boolean[] flag = new boolean[n];
for(int i = 0;i < n;++i){
flag[nums[i] - 1] = true;
}
List<Integer> res = new ArrayList<>();
for(int i = 0;i < n;++i){
if(flag[i] == false) res.add(i + 1);
}
return res;
}
}
法二:哈希集合
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
int n = nums.length;
Set<Integer> counts = new HashSet<>(n);//提前指定HashSet尺寸,可避免扩容不必要的时间浪费
for(int num : nums) counts.add(num);
List<Integer> res = new ArrayList<>();
for(int i = 1;i <= n;++i){
if(!counts.contains(i)) res.add(i);
}
return res;
}
}
法三:
遍历数组,将每个数字交换到它理应出现的位置上,下面情况不用换:
当前数字本就出现在理应的位置上,跳过,不用换。
当前数字理应出现的位置上,已经存在当前数字,跳过,不用换。
再次遍历,如果当前位置没对应正确的数,如上图索引 4、5,则将对应的 5、6 加入 res。
一定要注意,循环中的 i 不是每次循环都自增的,要符合条件才回自增。
所以以下代码是错误的。
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
//错误的代码
List<Integer> res = new ArrayList<>();
int n = nums.length;
for(int i = 0;i < n;++i){
if(nums[i] == i + 1) continue;
int idealIdx = nums[i] - 1;
if(nums[i] == nums[idealIdx]) continue;
int tmp = nums[i];
nums[i] = nums[idealIdx];
nums[idealIdx] = tmp;
}
for(int i = 0;i < n;++i){
if(nums[i] != i + 1){
res.add(i + 1);
}
}
return res;
}
}
以下才是正确的
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> res = new ArrayList<>();
int i = 0;
while (i < nums.length) {
if (nums[i] == i + 1) {
i++;
continue;
}
int idealIdx = nums[i] - 1;
if (nums[i] == nums[idealIdx]) {
i++;
continue;
}
int tmp = nums[i];
nums[i] = nums[idealIdx];
nums[idealIdx] = tmp;
}
for (int j = 0; j < nums.length; j++) {
if (nums[j] != j + 1) {
res.add(j + 1);
}
}
return res;
}
}