欢迎来到尧图网

客户服务 关于我们

您的位置:首页 > 新闻 > 会展 > 【Leetcode】位运算之只出现一次的数字I、III

【Leetcode】位运算之只出现一次的数字I、III

2025/6/21 0:39:09 来源:https://blog.csdn.net/2501_90265152/article/details/148669638  浏览:    关键词:【Leetcode】位运算之只出现一次的数字I、III

文章目录

  • 位运算总结
    • 基础位运算
    • 确定一个数n的二进制表示中的第X位是0还是1
    • 将一个数n的二进制表示中的第X位修改成1
    • 将一个数n的二进制表示中的第X位修改成0
    • 提取一个数n二进制表示中最右侧的1(lowbit)
    • 消除一个数n二进制表示中最右侧的1
    • 异或运算的运算律
  • 只出现一次的数字I
    • 题目链接
    • 题目描述
    • 解题思路
    • 代码
  • 只出现一次的数字III
    • 题目链接
    • 题目描述
    • 解题思路
    • 代码


位运算总结

基础位运算

按位或:| (有1则为1)
按位与:&(有0则为0)
按位异或:^(相同为0相异为1 无进位相加)
如何理解无进位相加,我们看下面这个例子:

在这里插入图片描述

确定一个数n的二进制表示中的第X位是0还是1

在这里插入图片描述

将一个数n的二进制表示中的第X位修改成1

在这里插入图片描述

将一个数n的二进制表示中的第X位修改成0

这道题和上面基本一致,只不过是先把1左移X位后把结果按位取反后再和数n相与:
n &= (~(1 << x))

提取一个数n二进制表示中最右侧的1(lowbit)

把n按位取反后加1再与1相与: n & -n(在计算机中,复数通常用补码表示)

在这里插入图片描述

消除一个数n二进制表示中最右侧的1

n & (n - 1)
n - 1的目的:把最右侧的1右边区域的数(包含1)全部变成相反。

在这里插入图片描述

异或运算的运算律

  • a ^ 0 = a
    在这里插入图片描述

  • a ^ a = 0(消消乐)
    在这里插入图片描述

  • a ^ b ^ c = a ^ (b ^ c)

也就是说一堆数据相异或结果一定是唯一的,结果和顺序无关。

只出现一次的数字I

题目链接

题目链接

题目描述

在这里插入图片描述

解题思路

这道题用的是异或运算律,把整数数组里的数全部异或在一起,出现偶数次的自然就消为0了,最后出现一次的数和0异或结果就是它本身。

代码

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

只出现一次的数字III

题目链接

题目链接

题目描述

在这里插入图片描述

解题思路

  • 这道题还是用异或运算律来求解,先把所有数据异或到一起,最后结果是两个只出现一次的元素相异或的结果,所以需要执果索因,要通过这个结果找到这两个元素。
    思路就是把全部数据分成两部分,每部分分别包含这两个元素的其中一个,这样每一部分就降维成上一题了。
  • 现在的问题就是找到以什么条件来区分这两部分,这就需要我们抓住异或的特点,两个数据相异或得到的结果的二进制表示中,若其中某一位是1,那么这两个数据的二进制表示中相应的位一定是不同的,一个1,一个0,这样才符合异或规律。
  • 有了这个思路,我们不难想到要找结果的二进制表示中的其中一个1,也就是把这个1提取出来,再用这个提取出来的1分别与所有数据相与,结果为0分到同一组,非01分到另外一组。
  • 但是这里要特别注意处理结果溢出风险,当结果为INT_MIN时,其二进制表示为100…00(32位),如果把它按位取反再加一就超出的整型最大值了,所以当当结果为INT_MIN时就不用x&(-x)了,因为它本身就只有一位是1,直接用它去和所有数据相与。

代码

class Solution {
public:vector<int> singleNumber(vector<int>& nums) {int x = 0;for(int i = 0; i < nums.size(); i++){x ^= nums[i];}//防止溢出int w = x == INT_MIN ? x : x & (-x);int m = 0;int n = 0;for(auto ch : nums){if(ch & w){m ^= ch;}else{n ^= ch;}}return {m, n};}
};

以上就是小编分享的全部内容了,如果觉得不错还请留下免费的关注和收藏
如果有建议欢迎通过评论区或私信留言,感谢您的大力支持。
一键三连好运连连哦~~

在这里插入图片描述

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com

热搜词