丢失的数字
给定一个包含 [0, n] 中 n 个数的数组 nums ,找出 [0, n] 这个范围内没有出现在数组中的那个数。
示例 1:
输入:nums = [3,0,1]
输出:2
解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,因为它没有出现在 nums 中。
示例 2:
输入:nums = [0,1]
输出:2
解释:n = 2,因为有 2 个数字,所以所有的数字都在范围 [0,2] 内。2 是丢失的数字,因为它没有出现在 nums 中。
示例 3:
输入:nums = [9,6,4,2,3,5,7,0,1]
输出:8
解释:n = 9,因为有 9 个数字,所以所有的数字都在范围 [0,9] 内。8 是丢失的数字,因为它没有出现在 nums 中。
示例 4:
输入:nums = [0]
输出:1
解释:n = 1,因为有 1 个数字,所以所有的数字都在范围 [0,1] 内。1 是丢失的数字,因为它没有出现在 nums 中。
对于上述题目我们有几种解法
1.将数组中的数据进行升序排序用后一个数据-上一个数据不等于1,则用后面的数据减1找到丢失的数字。
void Bubble_sort(int* arr, int sz)
{int i = 0;for (i = 0; i < sz - 1; i++)//确定排序的趟数{int j = 0;int flag = 1;//如果arr[j]<arr[j+1],就不用进入循环,加快效率for (j = 0; j < sz - 1 - i; j++){//两两比较,交换排序if (arr[j] > arr[j + 1]){flag = 0;//发生交换就说明无序int tmp = arr[j + 1];arr[j + 1] = arr[j];arr[j] = tmp;}if (flag == 1)//没有进入循环break;}}
}
void FindMissNum(int* arr, int n)
{Bubble_sort(arr , n);for (int i = 0; i < n; ++i){if (i + 1 == n)//防止越界{break;}if ((arr[i + 1]- arr[i])!=1 ){printf("丢失的数字为%d\n", arr[i + 1]-1);break;} }
}
int main()
{int num[] = { 3,1,0,2,4,9,5,6,7,10 };int sz = sizeof(num)/sizeof(num[0]);FindMissNum(num, sz);return 0;
}
虽然上述代码可以解决问题,但是时间复杂度为O(n),效率低
2.将数组中0-(n-1)的数据相加得到num1,再将0-n的数据相加得到num2,将num2-num1得出的结果就是丢失的数字。
void FindMissNum2(int* arr, int sz)
{int i = 0;int j = 0;int sum1 = 0; int sum2 = 0;for (i = 0; i < sz; i++)//将数组中的所以数据相加{int tmp1 = arr[i];sum1 = tmp1 + sum1;}for (j = 0; j < sz +1; j++)//将0~n的数字相加{int tmp2 = j;sum2 = tmp2+sum2;}int missnum = sum2 - sum1;printf("丢失的数字是%d\n",missnum);
}
int main()
{int num[] = { 3,1,0,2,4,9,5,6,7,10 };int sz = sizeof(num)/sizeof(num[0]);FindMissNum2(num, sz);return 0;
}
上述代码的时间复杂度为O(1),空间复杂度为O(n),不推荐
3.将数组中的数据全部异或,再与0-n全部异或,得出的结果就是丢失的数字。
(原理:任何数字异或自己之后就会抵消,异或的交换律)
void FindMissNum3(int* arr, int sz)
{int tmp1 = 0;int tmp2 = 0;for (int i = 0; i < sz; ++i){tmp1 = tmp1 ^ arr[i];}for (int j = 0; j < sz + 1; j++){tmp2 = tmp2 ^ j;}int missnum = tmp1 ^ tmp2;printf("丢失的数字是%d\n", missnum);
}
int main()
{int num[] = { 3,1,0,2,4,9,5,6,8,10 };int sz = sizeof(num)/sizeof(num[0]);FindMissNum3(num,sz);return 0;
}
上述代码的时间复杂度为O(1),且空间复杂度也为O(1),推荐使用