问题描述
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.
给一个1 <= a[i] <= n(n是数组长度)的数组,一些元素出现两次,其他出现一次。
找到所有没有出现在[1,n]中的元素。
你能否不用额外的空间并且在O(n)的运行时间之内完成?您可能认为返回的列表不算额外的空间。
举例说明
Example:
Input: [4,3,2,7,8,2,3,1] Output: [5,6]
思路
这道题关键是要找到没有出现的数字。首先元素是在[1,n]范围内,并且元素是整形,数组长度为n。如果将元素出现次数进行计数,计数为0的元素肯定就是我们要返回的。现在元素的范围我们是知道的,元素的长度我们也知道且它和元素范围相关。而一个长度为n+1的数组arr恰好能作为元素[1,n]的计数器(arr[0]不算,因为0不属于[1,n])。最后便利arr,如果元素为0,就为数组re的元素赋值arr的索引。
实现
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize){
int *arr = (int*)malloc((numsSize + 1) * sizeof(int));
int i, j, count = 0;
for (i = 0; i <= numsSize; i++)
arr[i] = 0;
for (i = 0; i < numsSize; i++) {
arr[nums[i]]++;
}
arr[0] = 1;
for (i = 1; i <= numsSize; i++) {
if (arr[i] == 0)
count++;
}
*returnSize = count;
int* re = (int*)malloc(count * sizeof(int));
for (i=0,j=0; i < count; j++) {
if(arr[j]==0)
{
re[i]=j;
i++;
}
else
continue;
}
free(arr);
arr = NULL;
return re;
}
反思
这个关键点其实是借鉴了别人的想法。时间复杂度太高了,待优化。