LeetCode-面试题 17.04. 消失的数字 超详细思路及过程[E]

在这里插入图片描述

题目描述

面试题 17.04. 消失的数字
难度:简单
相关标签:位运算、数组、哈希表、数学、排序

提示
数组nums包含从0到n的所有整数,但其中缺了一个。请编写代码找出那个缺失的整数。你有办法在O(n)时间内完成吗?
注意:本题相对书上原题稍作改动

运行示例
示例 1
输入:[3,0,1]
输出:2

示例 2
输入:[9,6,4,2,3,5,7,0,1]
输出:8

题目分析与实现

拿到这个题,我在想:如果给的输入是有序的,再挨个遍历,如果两个相邻元素的差大于1,这不就可以了找到缺失的那个数据了嘛。既然它给出的输入无序,那我就先给它排个序。
在这里插入图片描述

方法一:排序
class Solution {
public:
    int missingNumber(vector<int>& nums) {
        sort(nums.begin(), nums.end());
        int n = nums.size();
        for(int i = 0; i < n; i++)
        {
            if(nums[i] != i)
            {
                return i;
            }
        }
        return n;
    }
};

一波操作猛如虎,再看题目——O(n)时间复杂度。“你伤害了我,却一笑而过~~
在这里插入图片描述
喝口咖啡压压惊,再来想想。💡bink->数学方法求解:先通过等差数列求和公式求解0到n的和,在遍历的过程中,将各个元素减掉,剩下的值就是缺失的数字。
在这里插入图片描述

方法二:数学
class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n = nums.size();
        int sum = (1 + n) * n / 2;
        for(int i = 0; i < n; i++)
        {
            sum -= nums[i];
        }
        return sum;
    }
};

这个方法完全是依赖数学计算了。实现得非常完美——O(n)算法时间复杂度 O(1)空间复杂度。但实现完这些后,我们还要想想有没有别得解决方法。

也许会想到哈希表。咱先说说它有什么特点呢?哈希表存储的数据唯一,不能重复,且其时间复杂度极低,为O(n)。那么我们可以这么做:先将输入数组元素全部放入到哈希表中,再对0到n的元素进行查找,如果查找不到,那么它就是缺失的数字。

因为我们只有一个数值,不需要键值和数值对应,因此选择哈希集合会更有效地减少空间。

方法三:哈希表/哈希集合
class Solution {
public:
    int missingNumber(vector<int>& nums) {
        unordered_set<int>hash;
        int n = nums.size();
        for(int i = 0; i < n; i++)
        {
            hash.insert(nums[i]);
        }
        int missingNum = -1;
        for(int i = 0; i <= n; i++)
        {
            auto ret = hash.find(i);
            if(ret == hash.end())
            {
                missingNum = i;
                break;
            }
        }
        return missingNum;
    }
};

写完上面的算法,我心身疲惫。但再看看题目标签——“位运算”。这里到底应该如何使用位运算法呢?这个方法应该算是整个题目最难的解法了,但懂得之后就很轻松了。

首先,一起回顾一下异或运算。异或运算时,两个位若相同,则异或结果为0,两个位若不同,则异或结果为1。若两个数相同,则其二进制表示也相同,即各个位均相同。因此,两个相同的数异或结果应为0。
在这里插入图片描述
如果我们使用0与1和2进行异或运算,1的二进制表示为0000 0001,2的二进制表示为0000 0010。0与1异或结果为1,再与2异或结果为3。若输入数组为0、1,缺失的数组为2。此时将0、1、2异或操作后的结果与0和1分别异或,会发现结果为2。
在这里插入图片描述
若我们将0与0到n的各个数进行异或,再对用户输入的数组的各个元素进行异或,则异或后结果就是缺失的数字。

方法四:位运算
class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n = nums.size();
        int storage = 0 ^ n;
        for(int i = 0; i < n; i++)
        {
            storage ^= i;
            storage ^= nums[i];
        }
        return storage;
    }
};

上面就是今天分享的所有内容啦!下一文章见!
在这里插入图片描述
🎇有更优秀的算法,欢迎在评论区讨论!!

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值