题目链接:
题目:
Given an array containing n distinct numbers taken from
0, 1, 2, ..., n
, find the one that is missing from the array.Example 1:
Input: [3,0,1] Output: 2
Example 2:
Input: [9,6,4,2,3,5,7,0,1] Output: 8
Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
题目分析:
给定从0到n之中取出n个数作为数组,找出缺少的那个数。希望时间复杂度是线性的,空间复杂度是常数。
解题思路:
思路一:
首先想到的就是进行升序排序,然后将数组下标和该数比对,相同就下一位,不同说明缺少的数是下标对应的那个数。
但这种方法的由于用到了排序,所以时间复杂度是O(nlogn)。
思路二:
可以将数组全部求和,然后用本来的0到n的所有之和(等差数列求和)减去所有数组之和。这样子得到的值就是缺少的数。
这种方法只需要遍历一遍数组,所以时间复杂度是O(n),同时不需要额外的空间,所以空间复杂度是O(1)。
思路三:
还有一种方法,是之前我在小米OJ上做过一道题,就是一个数组里,所有数都出现两遍,只有一个数出现一遍,要求找出出现一遍的那个数是多少。这道题用到的方法是将数组里的所有数进行异或,因为相同的数异或为0,0和一个数异或还是那个数本身,这样子就可以求出那个出现一次的数。
在这道题里,也可以由这个思路来,用一个玩完整的0到n数组和本身的数组,当然不用额外存储一个数组,就用本来的数组下标即可。
所以时间复杂度是O(n),空间复杂度是O(1)。
AC代码:
思路一(这种方法代码就不贴了)。
思路二:
class Solution {
public:
int missingNumber(vector<int>& nums) {
int sum = 0;
for(int i = 0;i < nums.size();i++)
{
sum += nums[i];
}
int ans = (nums.size()+1)*(nums.size())/2 - sum;
return ans;
}
};
思路三:
class Solution {
public:
int missingNumber(vector<int>& nums) {
int ans = 0;
for(int i = 0;i < nums.size();i++)
{
ans = ans^nums[i]^(i+1);
}
return ans;
}
};