268. Missing Number (Easy)

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?

Solution 1: Math 22ms

这道题给我们n个数字,是0到n之间的数但是有一个数字去掉了,让我们寻找这个数字,要求线性的时间复杂度和常数级的空间复杂度。那么最直观的一个方法是用等差数列的求和公式求出0到n之间所有的数字之和,然后再遍历数组算出给定数字的累积和,然后做减法,差值就是丢失的那个数字,参见代码如下:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n = nums.size();
        int sum = (n+1)*n/2;
        for (int num: nums) sum -= num;
        return sum;
    }
};

Solution 2: Bit Manipulation 26ms

这题还有一种解法,使用位操作Bit Manipulation来解的,用到了异或操作的特性,相似的题目有Single Number 单独的数字, Single Number II 单独的数字之二和Single Number III 单独的数字之三。那么思路是既然0到n之间少了一个数,我们将这个少了一个数的数组合0到n之间完整的数组异或一下,那么相同的数字都变为0了,剩下的就是少了的那个数字了,参加代码如下:

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int res = 0;
        for (int i = 0; i < nums.size(); ++i) {
            res ^= (i+1)^nums[i];
        }
        return res;
    }
};

Solution 3: Binary Search

这道题还可以用二分查找法来做,我们首先要对数组排序,然后我们用二分查找法算出中间元素的下标,然后用元素值和下标值之间做对比,如果元素值大于下标值,则说明缺失的数字在左边,此时将right赋为mid,反之则将left赋为mid+1。那么看到这里,作为读者的你可能会提出,排序的时间复杂度都不止O(n),何必要多此一举用二分查找,还不如用上面两种方法呢。对,你说的没错,但是在面试的时候,有可能能人家给你的数组就是排好序的,那么此时用二分查找法肯定要优于上面两种方法,所以这种方法最好也要掌握以下~

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int low = 0, high = nums.size()-1;
        while (low <= high) {
            int mid = (low+high)/2;
            if (nums[mid] > mid) high = mid;
            else low = mid+1;
        }
        return low;
    }
};

results matching ""

    No results matching ""