《算法零基础100讲》(第47讲) 位运算 (异或) 进阶

Posted 英雄哪里出来

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了《算法零基础100讲》(第47讲) 位运算 (异或) 进阶相关的知识,希望对你有一定的参考价值。

零、写在前面

  这是《算法零基础100讲》 专栏打卡学习的第四十六天了。
  每天打卡的题,做不出来没关系,因为困难的题涉及知识点较多,后面还是会开放出来的,就像昨天的 最大公约数 那道题今天还是会有,所以不要着急,内容能看懂,能自己分析,能做出简单题,就可以打卡。
  在刷题的过程中,总结自己遇到的坑点,写出 「 解题报告 」 供他人学习,也是一种自我学习的方式。这就是经典的帮助他人的同时,成就自己。目前, 「 万人千题 」 社区 每天都会有五六篇高质量的 「 解题报告 」 被我 「 加精 」。如果觉得自己有能力的,也可以来发布你的 「 解题报告 」。千万级流量,你我共同拥有。

一、概念定义

  有关异或运算的概念,我们已经在 《算法零基础100讲》(第46讲) 位运算 (异或) 入门 学得差不多了,这一章节重要来看下,异或有哪些应用点。

二、题目描述

  给定一个整数数组 nums,其中恰好有两个元素只出现一次,其余所有元素均出现两次。 找出只出现一次的那两个元素。你可以按 任意顺序 返回答案。请利用线性复杂度来完成问题。

三、算法详解

  首先,只有两个数出现一次,其他数都出现两次,所以所有数异或的结果一定为非零值,并且一定是这两个数的异或结果,即 sum = a XOR b
  那么在sum的二进制位中找到一个为 1的位,假设第 i i i 位为1,则用 2 i 2^i 2i 作为掩码;
  将所有数和 2 i 2^i 2i进行位与,得到结果不为零的归为一组,异或以后的到a,再用a求得b = sum XOR a

四、源码剖析

int* singleNumber(int* nums, int numsSize, int* returnSize)
    int i, j;
    int sum = 0;
    int *ret = (int *)malloc( sizeof(int) * 2 );      // (1) 
    *returnSize = 2;
    for(i = 0; i < numsSize; ++i )                   // (2)
        sum ^= nums[i];
    
    ret[0] = ret[1] = 0;
    for(i = 0; i < 32; ++i) 
        if( sum & ((unsigned int)1<<i) )             // (3)
            for(j = 0; j < numsSize; ++j) 
                if(nums[j] & ((unsigned int)1<<i))   // (4)
                    ret[0] ^= nums[j];
                else 
                    ret[1] ^= nums[j];                // (5)
                
            
            break;
        
    
    return ret;

  • ( 1 ) (1) (1) 申请两个数的空间;
  • ( 2 ) (2) (2) 将所有数异或后得到sum
  • ( 3 ) (3) (3) 如果sum i i i 位为1,则取 2 i 2^i 2i 作为掩码;
  • ( 4 ) (4) (4) 和掩码 位与 结果非零的,异或完的结果就是其中一个数;
  • ( 5 ) (5) (5) 否则,异或完结果就是另一个数;

五、推荐专栏

🌌《算法零基础100讲》🌌

(第46讲) 异或入门

六、习题练习

序号题目链接难度
1只出现一次的数字 III★★☆☆☆
2翻转矩阵后的得分★★★☆☆
3形成两个异或相等数组的三元组数目★★★☆☆

以上是关于《算法零基础100讲》(第47讲) 位运算 (异或) 进阶的主要内容,如果未能解决你的问题,请参考以下文章

《算法零基础100讲》(第49讲) 位运算 (右移)

《算法零基础100讲》(第48讲) 位运算 (左移)

《算法零基础100讲》(第44讲) 位运算 (位或) 入门

《算法零基础100讲》(第50讲) 位运算 (按位取反)

《算法零基础100讲》(第45讲) 位运算 (位或) 进阶

《算法零基础100讲》(第58讲) 前缀和 线性前缀和变形