LeetCode只出现一次的数字I~III(位运算)

136. 只出现一次的数字
题目描述

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现两次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,1]
输出: 1
示例 2:
输入: [4,1,2,1,2]
输出: 4

解题思路
位运算:
从头到尾对每个数进行一遍^运算最后得到的那个数就是出现一次的数,因为相同的数^后的结果为0

	int singleNumber(vector<int>& nums) {
        int ans = 0;
        for(int i = 0; i < nums.size(); i++)
        {
            ans ^= nums[i];
        }
        return ans;
    }

137. 只出现一次的数字 II
题目描述

给定一个非空整数数组,除了某个元素只出现一次以外,其余每个元素均出现了三次。找出那个只出现了一次的元素。
说明:
你的算法应该具有线性时间复杂度。 你可以不使用额外空间来实现吗?
示例 1:
输入: [2,2,3,2]
输出: 3
示例 2:
输入: [0,1,0,1,0,1,99]
输出: 99

解题思路
位运算:
为了区分出现一次的数字和出现三次的数字,使用两个位掩码:seen_once 和 seen_twice。
仅当 seen_twice 未变时,改变 seen_once。
仅当 seen_once 未变时,改变seen_twice。
在这里插入图片描述
位掩码 seen_once 仅保留出现一次的数字,不保留出现三次的数字。

    int singleNumber(vector<int>& nums) {
        int twice = 0, once = 0;
        for(auto x:nums)
        {
            once = ~twice&(once^x);
            twice = ~once&(twice^x);
        }
        return once;
    }

260. 只出现一次的数字 III
题目描述
在这里插入图片描述
位运算-设置两个掩码

本文将使用两个按位技巧:

使用异或运算可以帮助我们消除出现两次的数字;我们计算 bitmask ^= x,则 bitmask 留下的就是出现奇数次的位。
在这里插入图片描述
x & (-x) 是保留位中最右边 1 ,且将其余的 1 设位 0 的方法。
在这里插入图片描述
算法:

首先计算 bitmask ^= x,则 bitmask 不会保留出现两次数字的值,因为相同数字的异或值为 0。

但是 bitmask 会保留只出现一次的两个数字(x 和 y)之间的差异。
在这里插入图片描述
我们可以直接从 bitmask 中提取 x 和 y 吗?不能,但是我们可以用 bitmask 作为标记来分离 x 和 y。

我们通过 bitmask & (-bitmask) 保留 bitmask 最右边的 1,这个 1 要么来自 x,要么来自 y。
在这里插入图片描述
当我们找到了 x,那么 y = bitmask^x。

    vector<int> singleNumber(vector<int>& nums) {
        int bitcheck = 0;
        for(int x : nums) bitcheck ^= x;
        // 剔除最右边的 1 把它当做特征位
        int flag = bitcheck & (-bitcheck); // -bitcheck => (~bitcheck + 1)
        int x = 0;
        // 将全部有特征位的数相与 剩余最后的 x 就是其中一个只出现一次的元素
        for(int num : nums) if(num & flag) x ^= num;
        return {x,bitcheck ^ x};
    }

注: 本文题解引用自LeetCode官方题解

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值