法1:
数组元素取值范围为1~n,数组大小为n,因此可以用另一个长度为n的数组counts统计数组元素出现的次数,再遍历一遍counts数组,输出数组值为0的下标。时间复杂度O(n),空间O(n)。
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
//取值范围1-n,元素个数n
//使用一个大小为n+1的数组counts记录每个元素出现的次数
//遍历counts,输出次数为0的数
List<Integer> res = new ArrayList<Integer>();
int[] counts = new int[nums.length+1];
for(int i=0;i<nums.length;i++){
counts[nums[i]] = counts[nums[i]]+1;
}
for(int j=1;j<counts.length;j++){
if(counts[j]==0)
res.add(j);
}
return res;
}
}
改进:
原地修改nums,遍历nums,将出现的数字值-1位置处的数组值置为其负数。
随后再次遍历nums,不为负数的位置其下标+1即为未出现的数。
class Solution {
public List<Integer> findDisappearedNumbers(int[] nums) {
//原地修改nums,遍历nums,将nums[nums[i]-1]修改为负数
//再次遍历nums,不为复数的位置说明该位置对应的数字未出现
List<Integer> res = new ArrayList<Integer>();
for(int num:nums){
int pos = Math.abs(num) - 1;
if(nums[pos]>0)
nums[pos] = -nums[pos];
}
for(int i=0;i<nums.length;i++){
if(nums[i] > 0){
res.add(i+1);
}
}
return res;
}
}