Given an array of integers where 1 ≤ a[i] ≤ n (n = size of array), some elements appear twice and others appear once.
Find all the elements of [1, n] inclusive that do not appear in this array.
Could you do it without extra space and in O(n) runtime? You may assume the returned list does not count as extra space.
Example:
Input: [4,3,2,7,8,2,3,1] Output: [5,6]
题意:
给定一个数组,数组中的每个元素的大小限制在,,n为数组的长度,数组中的元素出现的次数为零次,一次或者两次,求出数组中缺失的元素。
解题思路:
1.自己的想法
从第一个元素开始遍历数组,index = nums[i] - 1记录的是数组中元素的对应位置,如果数组中的nums[i] != nums[index],那么交换nums[i]和nums[index]对应的数值,依次交换下去,交换停止的条件是nums[i] == nums[index],即第i位置上放置了i-1,或者index上放置了对应的数值。
第二次遍历,如果nums[i] != i+1,说明nums[i]是重复的数字,并且i+1在数组中是缺失的。
代码如下:
public static List<Integer> findDisappearedNumbers2(int[] nums) {
List<Integer> result = new ArrayList<>();
if(nums == null || nums.length == 0)
return result;
int i = 0;
while(i < nums.length) {
int index = nums[i] - 1;
if(nums[i] != nums[index]) {
int temp = nums[i];
nums[i] = nums[index];
nums[index] = temp;
}else {
i++;
}
}
for(i = 0; i < nums.length; i++) {
if(nums[i] != i+1)
result.add(i+1);
}
return result;
}
2 leetcode上最高赞答案:
从前向后遍历数组,index=nums[i]-1记录的是该元素对应的位置。遍历后,该元素对应位置上的元素置为负值。
第二次遍历数组,如果有的位置上的元素为正值,说明该位置在第一次遍历中没有遍历到,因此,i+1是缺失的元素。
public static List<Integer> findDisappearedNumbers1(int[] nums) {
List<Integer> result = new ArrayList<>();
if(nums == null || nums.length == 0)
return result;
for(int i = 0; i < nums.length; i++) {
int index = Math.abs(nums[i]) - 1;
if(nums[index] > 0)
nums[index] = -nums[index];
}
for(int i = 0; i < nums.length; i++){
if(nums[i] > 0)
result.add(i+1);
}
return result;
}