前言
Missing Number是一道和Single Number很像的题(无论是从名字还是解法的角度而言),具体思路并不难,做法倒是不少。
题目
https://leetcode.com/problems/missing-number/
Given an array containing n distinct numbers taken from 0, 1, 2, …, n, find the one that is missing from the array.
For example,
Given nums = [0, 1, 3] return 2.
Note:
Your algorithm should run in linear runtime complexity. Could you implement it using only constant extra space complexity?
说是给出n个数字,范围为0到n且不重复,找出那个没有出现的数字。(0-n共有n+1个数字)
思路
首先可以想到的做法就是求和。显而易见,这是个(如果Missing Number并没有Miss的话)等差数列,由0到n,中学数学知识告诉我们,它们的和是
sum = (0 + n) * (n + 1) / 2
那么只要从这个和中减去所有出现的n个数字,最后得到的就是那个Missing Number。这个思路最为直接,代码也最为简洁。
第二种做法,灵感来源于著名的Single Number。给出的数组是0-n之间的n个数字,而下标(index)则是从0一直到n-1。我们可以设想,这个Missing Number在数组中,也就意味着数组下标是0到n,那么这种情况下,下标(index)和数值(array element)是完全可以一一对应起来的。那么如果把下标的集合和元素的集合拼成一个集合,在这个集合中每个数字都将出现两次,但是Missing Number将只出现一次(只在下标集合中出现而不在元素集合中出现)。这时,Missing Number其实就是个Single Number了。
我们从0到n异或一遍,再把所有元素,即nums[0]到nums[n-1],全部异或一遍,最终就可以得到那个Missing的家伙。
第三种做法,也是很自然的思路。既然要找一个数字,那么我们很容易会想到经典的二分查找(Binary Search)。值得一提的是,这也是我在高考后的那个暑假看到的Harvard CS入门课程中介绍的第一个算法,因为它实在是太经典,太自然了。
在这道题中,我们先排序这个数组,然后不断二分查找,就可以轻而易举的找到Missing Number。关键语句是 nums[mid] > mid ,我们知道,排序后没有Missing Number的话,对于每个i,number[i] == i 都成立。而如果nums[mid] > mid,说明接下来应该排查mid左侧的部分(right = mid),否则排查右侧的部分(left = mid + 1)。最终就能锁定Missing的是Left。
代码
Solution 1 求和
class Solution {
public:
int missingNumber(vector<int>& nums) {
int len = nums.size();
int sum = (0 + len) * (len + 1) /2;
for (int i = 0; i < len; i++) {
sum -= nums[i];
}
return sum;
}
};
Solution 2 异或
class Solution {
public:
int missingNumber(vector<int>& nums) {
int res = 0;
for (int i = 0; i < nums.size(); i++) {
res ^= nums[i];
res ^= i;
}
res ^= nums.size();
return res;
}
};
Solution 3 二分查找
class Solution {
public:
int missingNumber(vector<int>& nums) {
sort(nums.begin(), nums.end());
int left = 0, right = nums.size(), mid;
while (left < right) {
mid = (left + right) /2;
if (nums[mid] > mid)
right = mid;
else
left = mid + 1;
}
return left;
}
};
本文介绍了寻找数组中缺失数字的三种高效算法:求和法、异或法及二分查找法,并提供了C++实现代码。
1358

被折叠的 条评论
为什么被折叠?



