给定一个数组,包含0,1,2…….n 的 n个数,输出缺失的那一个。
Input: [9,6,4,2,3,5,7,0,1]
Output: 8
思路:
因为 0 ~ n 共有 n+1个数,而给定的数组中只有 n 个数,n 取决于数组的长度;所以,不管如何,都缺失一个数,偏一点的例子,如: [0,1],则缺失的为2.
一、运用sort函数排序,再遍历,提交虽然AC,但时间复杂度有点高。
int missingNumber(vector<int>& nums) { sort(nums.begin(), nums.end()); for (int i = 0; i < nums.size(); i++) { if (nums[i] != i) return i; } return nums.size(); }
二、空间换时间,利用长为 n+1的数组,初始值都设为0,将给定数组中的值作为申请数组的下标,写入值为1。最后对数组遍历,还是初始值0的就是缺失的。
int missingNumber(vector<int>& nums) { int* tmp = new int[nums.size() + 1]; for (int i = 0; i < nums.size() + 1; i++) { tmp[i] = 0; } for (auto i : nums) { tmp[i] = 1; } for (int i = 0; i < nums.size() + 1; i++) { if (tmp[i] == 0){ delete[]tmp; return i; } } return 0; }
三、利用和差。
sum = n*(n+1) / 2; 用sum减去给定数组中的每一个值,得到结果。
int missingNumber(vector<int>& nums) { int n = nums.size(); int sum = n * (n + 1) / 2; for (int i = 0; i < n; i++) { sum -= nums[i]; } return sum; }
四、异或XOR,n ^ n = 0, n ^ 0 = n; 遍历的时候,nums[i] ^ i 利用交换律,可以将能配对的都配对一起,和 i 不能配对的就是最终结果。
但对于[0,1,2]这种,for循环遍历不到3,所以,定义 int res = nums.size( ).
int missingNumber(vector<int>& nums) { int n = nums.size(); int res = n; for (int i = 0; i < n; i++) { res = res ^ i ^ nums[i]; } return res; }