消失的数字
题目:
思路1:排序的方式
- 使用C语言库函数qsort()排序,这样数字就和数组下标相对应
- 然后遍历数组nums,用nums[ i+] 和 nums[ i-1 ]+1 判断是否相等
- 若不相等,把 nums[ i-1 ]+1 输出即可
实现代码:
#include <stdio.h>
#include <stdlib.h>// 比较函数,用于qsort
int compare(const void* a, const void* b)
{return (*(int*)a - *(int*)b);
}int missingNumber(int* nums, int numsSize)
{if (numsSize == 0) return 0;// 1. 排序数组qsort(nums, numsSize, sizeof(int), compare);// qsort(要排序的数组, 元素个数, 每个元素的大小, 比较函数)// 2. 检查第一个元素是否为0if (nums[0] != 0) {return 0;//如果第一个不是0,那么0就是缺失的数字}// 3. 检查中间缺失的数字for (int i = 1; i < numsSize; i++){if (nums[i] != nums[i - 1] + 1) //如果当前元素不等于前一个元素+1,说明中间有缺失{return nums[i - 1] + 1;//返回缺失的数字}}// 4. 如果前面都没找到,缺失的就是最后一个数字nreturn numsSize;
}// 测试代码
int main() {int nums1[] = { 3, 0, 1 };int size1 = sizeof(nums1) / sizeof(nums1[0]);printf("输入: [3,0,1]\n输出: %d\n\n", missingNumber(nums1, size1));int nums2[] = { 9, 6, 4, 2, 3, 5, 7, 0, 1 };int size2 = sizeof(nums2) / sizeof(nums2[0]);printf("输入: [9,6,4,2,3,5,7,0,1]\n输出: %d\n", missingNumber(nums2, size2));return 0;
}
注意:用于C语言的库qsort函数时间复杂度是O(nlogn),与题目不符合
思路二:哈希表的方式
- 开辟一个数组初始值赋为-1,然后对应下标保存对应数字
- 然后再遍历数组,发现为-1的值的下标就为消失数字
代码实现:
int missingNumber(int* nums, int numsSize)
{//开辟numsSize+1大小的数组int* newNums = (int*)malloc(sizeof(int)*(numsSize+1));//给数组赋值 -1for(int i = 0;i < numsSize+1;i++){newNums[i] = -1;}//给newNums数组赋nums的数字,把下标和数字对应映射起来for(int i = 0;i <numsSize;i++){newNums[nums[i]] = nums[i];}//找消失的数字int i = 0;for(i= 0;i <numsSize+1;i++){if(newNums[i] == -1)break;}return i;
}
思路三:相邻差值相减
- 直接先求0到n的累加和sum,然后遍历数组求和sumNums
- 用 sum - sumNums = 消失的数字
代码实现:
int missingNumber(int* nums, int numsSize)
{//先求 0 - n 的所有和//等差数列求和int n = numsSize + 1;int sum = 0;int i = 0;for (i = 0; i < n; i++){sum += i;}int sumNums = 0; //保存nums数组的和//求数组的和for (int j = 0; j<numsSize; j++){sumNums += nums[j];}//差值为消失的数字return sum - sumNums;
}
思路四:异或性质
异或性质:
- 0^x = x
- x^x = 0; 同样的数异或两次得到零
- 异或满足交换律,不需要考虑顺序
实现思路:
- 将[0,n]和nums数字的所有数字进行异或
- 由于相同的数异或会得到0,0异或任意数结果都是任意数
- 所以在本题中,异或两次的会被变为0,异或一次的就不会发生变化:那么消失的数字就会出来了
- 比如 输入:[3,0,1]
0到n的所有数字和[3,0,1]进行异或:0^ 1 ^ 2^ 3 ^ 3^ 0 ^ 1 = 0^ 1^ 1^ 2 ^3 ^3 = 2; 即2是消失的数字
代码实现:
int missingNumber(int* nums, int numsSize)
{//先异或0-numsSize的所有数字int x = 0;for(int i = 0 ;i<=numsSize;i++){x ^= i;}//再异或nums数组所有的值for(int i = 0;i <numsSize;i++){x ^= nums[i];}//最后的结果就是消失的数字return x;
}