位运算篇——位海拾遗,探秘数字世界的亚特兰蒂斯(2)

发布于:2024-12-18 ⋅ 阅读:(104) ⋅ 点赞:(0)

在这里插入图片描述

前言

上篇谈到了位运算的相关语法及原理和部分基础题目配合讲解,本篇将结合进阶题目,深化对于位运算的掌握运用。

一. 只出现一次的数字||

1.1 题目链接:https://leetcode.cn/problems/single-number-ii/description/

1.2 题目分析:

给定一个数组,该数组内除目标值外,其他值均出现了3次,要求找到该只出现一次的目标值。
时间复杂度为O(n),空间复杂度为O(1).

1.3 思路讲解:

比特位计数:

设要找的数位 ret 。
由于整个数组中,需要找的元素只出现了「⼀次」,其余的数都出现的「三次」,因此我们可以根
据所有数的「某⼀个⽐特位」的总和 %3 的结果,快速定位到 ret 的「⼀个⽐特位上」的值是
0 还是 1 。
这样,我们通过 ret 的每⼀个⽐特位上的值,就可以将 ret 给还原出来。

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ret=0;//目标值
        for(int i=0;i<32;i++)
        {
            int sum=0;
            for(auto x:nums)
            {
                if(x>>i&1)
                {
                    sum++;
                }
            }//每个比特位逐次累加
            sum%=3;
            if(sum==1)
            {
                ret|=1<<i;
            }
        }//循环32次确定ret每一个比特位的值
        return ret;
        
    }
};

二. 消失的两个数字

2.1 题目链接:https://leetcode.cn/problems/missing-two-lcci/

2.2 题目分析:

给定数组,范围为[1,n],但里面缺失了两个数字,要求返回这两个缺失数字,返回顺序不做要求。

2.3 思路讲解:

在消失的数字中,我们采用两轮异或的方式,即可直接求出,而本题有两个缺失的数字,我们又该如何处理呢?

  • 我们仍可以采取两轮异或的方式,即令sum=0,先与数组内每个元素异或,再与[1,n]内每个元素异或,此时结果即为缺失的数字a和b异或的值。
  • 为将a和b分别求出,我们首先需要找出a与b不同的比特位,由于异或的结果相同为0,相异为1,因此我们逐个右移判断,当值为1时即代表该比特位a与b不同。
  • 我们将该处位置记录为diff,假设a的diff位为1,b的diff位为0,a分别与数组内diff位的值位1的元素异或,b分别与数组内diff位的值位0的元素异或.
  • 最终返回a,b即可

2.4 代码实现:

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) {
        int n=nums.size();
        int sum=0;
        for(auto e:nums)
        {
            sum^=e;
        }
        for(int i=1;i<=n+2;i++)
        {
            sum^=i;
        }//两轮异或之后sum即为缺失数字a与b异或的结果
        int diff=0;
        while(1)
        {
            if(sum>>diff&1)
            {
                break;
            }
            else
            diff++;
        }//寻找a和b比特位不同的位置
        int a=0,b=0;
        for(auto e:nums)
        {
            if(e>>diff&1)
            {
                a^=e;

            }
            else
            {
                b^=e;
            }
        }
        for(int i=1;i<=n+2;i++)
        {
            if(i>>diff&1)
            {
                a^=i;
            }
            else
            {
                b^=i;
            }
        }//逐次异或
        return {a,b};
    }
};

三. 实际应用场景

  • 数据压缩与加密
    位运算常用于高效数据压缩算法,如哈夫曼编码,以及对数据进行快速加密与解密。

  • 硬件设计与信号处理
    在数字电路中,位运算是描述逻辑门操作的基础,例如AND、OR、XOR等。

  • 图形与图像处理
    位运算在位图处理与图像渲染中具有重要应用,通过掩码操作快速处理像素信息。

  • 高效算法设计
    位运算能显著优化算法的时间复杂度,尤其在需要频繁操作整数的场景中,如哈希函数、图论算法等。

小结

位运算在计算机科学中扮演着举足轻重的角色,它不仅以其高效和简洁让代码更具性能优势,还通过独特的逻辑体现了数学与工程的完美融合。在学习与实践中,善于发现和利用位运算的特性,能够让算法设计更加优雅,也能更深刻地理解计算机的底层逻辑。

“数尽千般妙,唯有位运藏。” 让我们以这一句诗作结,致敬位运算的奇妙世界。

关于位运算的介绍就暂告段落啦,希望能对大家的学习产生帮助,欢迎各位佬前来支持斧正!!!
在这里插入图片描述


网站公告

今日签到

点亮在社区的每一天
去签到