题目描述:
给定一个范围在 1 ≤ a[i] ≤ n ( n = 数组大小 ) 的 整型数组,数组中的元素一些出现了两次,另一些只出现一次。找到所有在 [1, n] 范围之间没有出现在数组中的数字。
您能在不使用额外空间且时间复杂度为O(n)的情况下完成这个任务吗? 你可以假定返回的数组不算在额外空间内。
样例:
输入:[4,3,2,7,8,2,3,1]
输出:[5,6]
分析:
数组长度为n,数字范围在1-n之间,因为有的元素出现了两次,所以这个数组中不能将该范围内的所有元素包含,目标找出未包含的元素。
如果不借助于额外的空间,则考虑从头遍历数组。
当遍历到第i个元素时,查看i+1是否等于nums[i],如果不等则找到第nums[i]-1个位置,查看该下标处的元素是否等于nums[i],如果相等则将nums[i]置为-1,如果不等则交换两个位置的元素。
直到遍历数组结束,进行第二次遍历,当该下标处的元素为-1时,证明该下标对应的元素缺失。
public List<Integer> findDisappearedNumbers(int[] nums) {
List<Integer> list=new ArrayList<>();
if(nums==null||nums.length==0)
return list;
for(int i=0;i<nums.length;i++) {
while(nums[i]!=-1&&nums[i]!=i+1) {//不要忘记nums[i]!=-1这个条件
int index=nums[i];
if(nums[index-1]==index) {
nums[i]=-1;
break;
}else {
int temp=nums[index-1];
nums[index-1]=index;
nums[i]=temp;
}
}
}
for(int i=0;i<nums.length;i++) {
if(nums[i]==-1)
list.add(i+1);
}
return list;
}