算法日常・每日刷题--<位运算>2

268. 丢失的数字 - 力扣(LeetCode)268. 丢失的数字 - 给定一个包含 0, n 中 n 个数的数组 nums ,找出 0, n 这个范围内没有出现在数组中的那个数。 示例 1:输入:nums = 3,0,1输出:2解释:n = 3,因为有 3 个数字,所以所有的数字都在范围 0,3 内。2 是丢失的数字,因为它没有出现在 nums 中。示例 2:输入:nums = 0,1输出:2解释:n = 2,因为有 2 个数字,所以所有的数字都在范围 0,2 内。2 是丢失的数字,因为它没有出现在 nums 中。示例 3:输入:nums = 9,6,4,2,3,5,7,0,1输出:8解释:n = 9,因为有 9 个数字,所以所有的数字都在范围 0,9 内。8 是丢失的数字,因为它没有出现在 nums 中。提示: * n == nums.length * 1 <= n <= 104 * 0 <= numsi <= n * nums 中的所有数字都 独一无二 进阶:你能否实现线性时间复杂度、仅使用额外常数空间的算法解决此问题?https://leetcode.cn/problems/missing-number/description/

一、题目题意

给定一个包含 [0, n]n 个整数的数组 nums,找出其中缺失的那个唯一数字。 示例:nums = [0,1,2,3,4,6],数组长度 n=6,完整区间应为 0~6,缺失数字是 5

二、异或运算核心性质(解题关键)

  1. 自消律x ^ x = 0,相同数字异或直接抵消为 0
  2. 归零律x ^ 0 = x,数字和 0 异或等于自身
  3. 交换律、结合律a ^ b ^ c = a ^ c ^ b,异或顺序不影响最终结果

三、解题思路(图文对应逻辑)

步骤拆解

  1. 数组内所有数字异或:res1 = 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 6
  2. 完整区间 0~n 全部数字异或:res2 = 0 ^ 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ 6
  3. 把两次结果再做异或:res1 ^ res2
    • 所有同时存在的数字(0、1、2、3、4、6)两两抵消变成 0
    • 只剩只出现在完整区间、数组里缺失的数字 5,即为答案
cpp 复制代码
class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int ret=0;
        for(auto e:nums)
        ret^=e;
        for(int i=0;i<nums.size()+1;i++)
        ret^=i;
        return ret;
    }
};