LeetCode 448. Find All Numbers Disappeared in an Array

来源:互联网 发布:《梦里花落知多少》 编辑:程序博客网 时间:2024/06/08 07:03

448. Find All Numbers Disappeared in an Array

Description

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]

Solution

  • 题目意思:输入n大小的一个数组,其中每个数字范围[1,n]。找出这些数中未在该范围内出现的数。
  • 暴力确实很很容易,但题目要求时间复杂度是O(N),不使用额外空间(返回的数组不包括在内)。
  • 我起初想的是开一个桶数组(初始化为0),遍历一遍原始数组,将数字放到对应的桶里面,比如nums[i] = 2,就将桶数组中nums[1](从0开始)置为1,表示存在,最后再遍历一次桶数组,将值为0的(表示不存在于原始数组)放到返回的数组里面。 这个想法的代码如下:
// 不标准代码,非最终int* findDisappearedNumbers(int* nums, int numsSize, int* returnSize) {    int len = 0;    int *rnt = (int *)malloc(sizeof(int) * numsSize);    int *bucket = (int *)malloc(sizeof(int) * numsSize);    memset(bucket,0,sizeof(bucket));    for (int i = 0;i < numsSize;i++) {        bucket[nums[i] - 1] = 1;    }    for (int i = 0;i < numsSize;i++) {        if (!bucket[i])            rnt[len++] = i + 1;    }    *returnSize = len;    return rnt;}
  • 但显然这个不满足题意对空间的要求(虽然也能AC),于是又想,我们使用第三方桶目的是什么呢,不就是标记某个数在不在数组中嘛? 我们能不能不用桶,在原数组中就能标记出来,桶是利用离散值(0,1)来标记某个数字在不在,原数组我们显然不能够改变数值来标记。
  • 那么我们需要一种标记方式,既能表示该下标对应的数字在不在数组中 又不影响我们获取这个下标当前存储的值。
  • 最终,可以用这么一种方式:如果某个数在数组中,那么将这个数对应的下标存储的位置用负数表示(注意到题目保证原始数组都是正数),那么就可以满足题意了,代码如下
//final versionint* findDisappearedNumbers(int* nums, int numsSize, int* returnSize) {    int len = 0;    int *rnt = (int *)malloc(sizeof(int) * numsSize);    for (int i = 0;i < numsSize;i++) {        if (nums[abs(nums[i]) - 1] > 0)            nums[abs(nums[i]) - 1] = - nums[abs(nums[i]) - 1];    }    for (int i = 0;i < numsSize;i++) {        if (nums[i] > 0)            rnt[len++] = i + 1;    }    *returnSize = len;    return rnt;}
阅读全文
0 0