首页 > 其他分享 >位运算篇——位海拾遗,探秘数字世界的亚特兰蒂斯(2)

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

时间:2024-12-16 10:28:11浏览次数:9  
标签:运算 int sum 异或 ret 位海 diff 探秘 亚特兰蒂斯

在这里插入图片描述

前言

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

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

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等。

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

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

小结

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

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

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

标签:运算,int,sum,异或,ret,位海,diff,探秘,亚特兰蒂斯
From: https://blog.csdn.net/2303_81060385/article/details/144386585

相关文章

  • 探秘 IIC 与 SPI:软件模拟与硬件接口的抉择之谜
    一、IIC软件模拟:受限中的灵活应变在嵌入式系统的通信世界里,IIC常采用软件模拟的方式开展工作,这背后有着诸多考量。首先,硬件资源的限制是一个重要因素。不少微控制器并没有内置功能完备的IIC硬件模块,甚至压根就不存在这样的模块。而软件模拟IIC则巧妙地绕开了这一硬件短......
  • C++游戏开发探秘【2】
    成长路上不孤单......
  • 探秘 SSM 校园一卡通密钥管理系统 PF:全方位保障密钥安全与高效运用
    第1章绪论1.1选题动因当前的网络技术,软件技术等都具备成熟的理论基础,市场上也出现各种技术开发的软件,这些软件都被用于各个领域,包括生活和工作的领域。随着电脑和笔记本的广泛运用,以及各种计算机硬件的完善和升级,市面上的电脑和笔记本的性能都得到提升,可以支持的软件也逐......
  • C++游戏开发探秘【1】
    成长路上不孤单......
  • e启学在线教育系统能否进行二次开发?探秘
    E启学在线教育系统支持二次开发,可以根据客户具体需求实现定制化改造和扩展,以更好地满足不同机构和个人在在线教育方面的特殊需要。这种灵活性为许多寻求高度定制和独特功能的企业和个人提供了有力的支持。图源www.tuzhi.ltd无论是增加新的功能、更改现有界面还是适应特定的教学流......
  • 探秘 Microi 吾码:强大的低代码平台全解析
    这里写目录标题探秘Microi吾码:强大的低代码平台全解析一、引言二、Microi吾码简介1.技术架构2.平台亮点三、快速开始1.安装方式1.介绍CentOS7一键安装脚本的使用方法和注意事项。2.详细说明安装过程中的各项配置和操作步骤。2.创建模块四、表单引擎1.V8.F......
  • 探秘Air780E低功耗模组LuatOS开发:洞悉数据打包解包(pack)!
    本文我们要探秘的是Air780E低功耗模组LuatOS开发,洞悉其数据打包解包(pack)!一、LuatOSstring库pack和unpack接口LuatOSstring库的pack和unpack是一个用于在Lua程序中进行二进制数据打包和解包操作的接口,支持多种数据类型和字节序格式,方便处理二进制协议和文件。由于Lua中字符......
  • Redis探秘Sentinel(哨兵模式)
    概述Redis的高可用机制有持久化、复制、哨兵和集群。其主要的作用和解决的问题分别是:持久化:持久化是最简单的高可用方法(有时甚至不被归为高可用的手段),主要作用是数据备份,即将数据存储在硬盘,保证数据不会因进程退出而丢失。复制:复制是高可用Redis的基础,哨兵和集群都是在复制......
  • 深入源代码,探秘Tomcat类加载机制:为何颠覆双亲委派原则(1)?
    1.什么是双亲委派 jvm启动后会通过其类装载子系统,去硬盘上找xxx.class文件,找到之后,会直接将xxx这个类装载到java虚拟机中,这个过程叫做类的加载。而类的加载过程中就涉及到了双亲委派。 类加载机制的双亲委派(ParentDelegationModel)是Java中的一种类加载策略,旨在确保Java......
  • Java 多线程探秘:核心概念与实用技巧全解析
    1.有三个线程T1,T2,T3,如何保证顺序执行?要确保三个线程T1,T2,和T3按顺序执行,你可以使用多种同步机制。以下是几种常见的方法:Join方法启动T1线程。调用T1.join(),这将使当前线程(假设是主线程)等待直到T1完成。启动T2线程,并调用T2.join()。最后启动T3线程,并......