给你一个含 n 个整数的数组 nums ,其中 nums[i] 在区间 [1, n] 内。请你找出所有在 [1, n] 范围内但没有出现在 nums 中的数字,并以数组的形式返回结果。
你能在不使用额外空间且时间复杂度为 O(n)
的情况下解决这个问题吗? 你可以假定返回的数组不算在额外空间内
int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize) {
int k = 0;
int* ret = malloc(sizeof(int) * numsSize);
*returnSize = 0;
for (int i = 0; i < numsSize; i++)
{
k = (nums[i] - 1) % numsSize;//
nums[k] += numsSize;
}
for (int j = 0; j < numsSize; j++)
{
if (nums[j] <= numsSize) {
ret[(*returnSize)++] = j + 1;
}
}
return ret;
}
4 3 2 7 8 2 3 1
0 1 2 3 4 5 6 7 (下标)
这道题不允许使用额外空间,但是这道题有一个特点“在[1, n] 范围内”可以与原数组的下标联系在一起,而且数组内的元素取值也是在[1, n] 范围内,将数组的每一个元素取出来,改变与这个取出来的元素的值相等的下标所对应的元素,将其加上数组的大小n,最后遍历数组,元素值小于n的元素对应的下标+1,就可以得到数组中消失的数字了。
4 3 2 7 8 2 3 1
0 1 2 3 4 5 6 7 (下标)
4-1=3,3—7,7+8=15;是这样一个过程
但是在我们改变的过程中,有些值还没有遍历到就已被改变了,
因此在我们遍历的过程中需要对其进行还原(nums[i] - 1) % numsSize,取模即可。