位运算算法:编程世界中的魔法符号

news2024/10/7 13:17:01

✨✨✨学习的道路很枯燥,希望我们能并肩走下来!

文章目录

目录

文章目录

前言

一. 常见位运算总结

二、常见位运算题目

2.1 位1的个数

2.2 比特数记位(典型dp)

 2.3 汉明距离

2.4 只出现一次的数字(1) 

2.5 只出现一次的数字(2)  

 2.6 只出现一次的数字(3)

 2.7  判断字符是否为1

2.8 丢失的数字

 2.9 两整数之和

 2.10 消失的两个数字

总结


前言

本篇详细介绍了位运算算法的使用,让使用者了解位运算,而不是仅仅停留在表面, 文章可能出现错误,如有请在评论区指正,让我们一起交流,共同进步!


一. 常见位运算总结

二、常见位运算题目

2.1 位1的个数

191. 位1的个数 - 力扣(LeetCode)

 利用第七条特性:n&(n-1)干掉最后一个1,然后每次都用count++去统计,直到变成0

class Solution {
public:
    int hammingWeight(int n) {
        int count = 0;
        while(n&(-n))
        {
            n&=(n-1);
            count++;
        }
        return count;
    }
};

2.2 比特数记位(典型dp)

338. 比特位计数 - 力扣(LeetCode)

 思路1:每遍历一个数都用n&(n-1)去数他一共有多少个1,然后放ret数组中

class Solution {
public:
    vector<int> countBits(int n) {
        vector<int> ret(n+1);
        for(int i = 0 ;i<=n;i++)
        {
            int m = i;
            int count = 0;
            while(m&(-m))
            {
                m&=(m-1);
                count++;
            }
            ret[i] = count;
        }
        return ret;

    }
};

 思路2:简单dp(前缀和 + 位运算

我们发现第i个位置的1的个数等于第i-1位置的1的个数+1

class Solution {
public:
    vector<int> countBits(int n) {
        vector<int> ret(n+1);
        for(int i = 1 ;i<=n;i++)
        {
            ret[i] = ret[i&(i-1)] + 1;
        }
        return ret;

    }
};

 2.3 汉明距离

461. 汉明距离 - 力扣(LeetCode)

        利用异或相同为0相异为1的特点,x和y异或后不一样的位都会变成1,这个时候再用n&(n-1)去统计1个个数,即为这两个数字的汉明距离 

class Solution {
public:
    int hammingDistance(int x, int y) 
    {
      //异或的特点,相同为0,相异为1     然后再利用n&(n-1)统计1的个数
      int n=x^y;
      int count=0;
      while(n)
      {
        n&=(n-1);
        ++count;
      }
      return count;
    }
};

2.4 只出现一次的数字(1) 

136. 只出现一次的数字 - 力扣(LeetCode) 

 思路:利用异或的性质,出现两次的数异或后为0,出现一次的数异或0还是本身 

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int value = 0;
        for(auto &e : nums)
        {
            value^=e;
        }
        return value;
    }
};

2.5 只出现一次的数字(2)  

137. 只出现一次的数字 II - 力扣(LeetCode) 

具体地,考虑答案的第 iii 个二进制位(iii 从 000 开始编号),它可能为 000 或 111。对于数组中非答案的元素,每一个元素都出现了 333 次,对应着第 iii 个二进制位的 333 个 000 或 333 个 111,无论是哪一种情况,它们的和都是 333 的倍数(即和为 000 或 333)。因此:

答案的第 iii 个二进制位就是数组中所有元素的第 iii 个二进制位之和除以 333 的余数。 

class Solution {
public:
    int singleNumber(vector<int>& nums) {
        int ans = 0;
        for (int i = 0; i < 32; ++i) {


            // 统计该每个数字第i个比特位为1的总数
            int total = 0;
            for (int num: nums) {
                total += ((num >> i) & 1);
            }


            // 如果total能够被3整除,说明只出现一次的数字在该位置上一定是0
            // 否则在该位置上一定是1
            if (total % 3) {
                ans |= (1 << i);
            }
        }
        return ans;
    }
};

 2.6 只出现一次的数字(3)

260. 只出现一次的数字 III - 力扣(LeetCode) 

 

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) 
    {
       unsigned int temp=0;//遇到INT_MIN会溢出,10000……00
       for(int num:nums) temp^=num;
       int x=temp&(-temp);//x拿到最后一个1,即两个数不同的地方
       //int x= (temp == temp ? temp : temp & (-temp));
       int type1=0,type2=0;
       for(int num:nums) if(num&x) value1^=num; else value2^=num;
       return {value,value};
    }
};

一般解法:

class Solution {
public:
    vector<int> singleNumber(vector<int>& nums) {
    sort(nums.begin(), nums.end());
    vector<int> res;
    int i = 0;
    for (; i < nums.size() - 1; ) 
    {
      if (nums[i] == nums[i + 1]) 
      {
        i += 2;
      } 
      else 
      {
        res.push_back(nums[i]);
        i += 1;
      }
    }
    if (i < nums.size()) 
    {
      res.push_back(nums[i]);
    }
    return res;     
  }
};

 2.7  判断字符是否为1

面试题 01.01. 判定字符是否唯一 - 力扣(LeetCode) 

class Solution {
public:
    bool isUnique(string astr) {
        // 利用鸽巢原理做优化
        if(astr.size()>26) return false;

        int bitMap = 0;
        for(auto& ch : astr)
        {
            int i = ch - 'a';
            // 先判断字符是否出现过
            if((bitMap>>i) & 1 == 1) return false;
            // 将当前字符加入到位图中
            bitMap |= (1<<i);
        }
        return true;
    }
};

2.8 丢失的数字

268. 丢失的数字 - 力扣(LeetCode) 

 

思路1:高斯公式

 

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n = nums.size();
        int ret = ((0 + n)*(n+1))/2;
        for(auto& e : nums)
        {
            ret -= e;
        }
        return ret;
    }
};

思路2:异或运算 

class Solution {
public:
    int missingNumber(vector<int>& nums) {
        int n = nums.size();
        int ret = 0;
        for(auto& e : nums) ret^=e;
        for(int i = 0;i<=n;i++) ret^=i;
        return ret;
    }
};

 2.9 两整数之和

371. 两整数之和 - 力扣(LeetCode) 

 

class Solution {
public:
    int getSum(int a, int b) {
        while(b != 0)
        {
            int x = a^b; //先算出无进位相加的结果
            unsigned int carry = (unsigned int)(a&b)<<1; //算出进位,//要考虑-1,因为-1的右移操作是没有定义的
            a = x;
            b = carry;
        }
        return a;
    }
};

 2.10 消失的两个数字

面试题 17.19. 消失的两个数字 - 力扣(LeetCode) 

 

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) {
        //1.将所有的数异或在一起
        int tmp = 0;
        for(auto& e : nums)
            tmp^=e;
        for(int i = 1;i<=nums.size()+2;i++)
            tmp^=i;
        //2. 找a,b中比特位不同的那一位
        int x = tmp&(-tmp);
        // 3. 根据比特位不同的那一位,划分成两类来异或
        int a = 0, b = 0;
        for(auto& e : nums)
        {
            if(e&x) a^=e;
            else    b^=e;
        }
        for(int i=1;i<=nums.size()+2;++i)
        {
            if(i&x) a^=i;  
            else  b^=i;
        }
        return {a,b};
    }
};

总结

✨✨✨各位读友,本篇分享到内容是否更好的让你理解位运算算法,如果对你有帮助给个👍赞鼓励一下吧!!
🎉🎉🎉世上没有绝望的处境,只有对处境绝望的人。
感谢每一位一起走到这的伙伴,我们可以一起交流进步!!!一起加油吧!!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1830612.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

JavaScript-事件监听

添加事件监听 语法&#xff1a;对象名.addEventListener(事件类型,要执行的函数) 作用&#xff1a;当事件触发时&#xff0c;就调用这个函数 事件类型&#xff1a;比如用鼠标点击&#xff0c;或用滚轮滑动&#xff0c;鼠标经过这些 要执行的函数&#xff1a;要做的事 &l…

区区微服务,何足挂齿?

背景 睿哥前天吩咐我去了解一下微服务&#xff0c;我本来想周末看的&#xff0c;结果周末没带电脑&#xff0c;所以只能周一看了。刚刚我就去慕课网看了相关的视频&#xff0c;然后写一篇文章总结一下。这篇文章算是基础理论版&#xff0c;等我之后进行更多的实践&#xff0c;…

【无标题】Pycharm执行报错

file 读取未指定utf-8编码&#xff0c;加上就好了 疑问&#xff1a;为什么 有的电脑可以直接跑呢&#xff1f;该电脑、Pycharm、工程&#xff0c;已经做了修改设置默认值&#xff0c;但是到新的电脑上&#xff0c;就需要重新设置&#xff0c;所以 file 读、写&#xff0c;最好…

[Shell编程学习路线]——if条件语句(单,双,多分支结构)详细语法介绍

&#x1f3e1;作者主页&#xff1a;点击&#xff01; &#x1f6e0;️Shell编程专栏&#xff1a;点击&#xff01; ⏰️创作时间&#xff1a;2024年6月17日7点50分 &#x1f004;️文章质量&#xff1a;95分 文章目录 ————前言———— &#x1f4af;趣站&#x1f4af…

【NOI】C++程序结构入门之循环结构四——带余除法

文章目录 前言一、带余除法1.1 概念1.2 编程中的使用1.2.1 模运算1.2.2 判断奇偶性1.2.3 判断倍数关系1.2.4 循环和迭代控制1.2.5 密码学与安全1.2.6 算法设计1.2.7 数据验证与错误处理 二、例题讲解问题&#xff1a;1389 - 数据分析问题&#xff1a;1750 - 有0的数问题&#x…

宕机了, redis如何保证数据不丢?

前言 如果有人问你&#xff1a;"你会把 Redis 用在什么业务场景下&#xff1f;" 我想你大概率会说&#xff1a;"我会把它当作缓存使用&#xff0c;因为它把后端数据库中的数据存储在内存中&#xff0c;然后直接从内存中读取数据&#xff0c;响应速度会非常快。…

IDEA快速入门03-代码头统一配置

三、代码规范配置 3.1 文件头和作者信息 配置入口&#xff1a;依次打开 File -> Settings -> Editor -> File and Code Templates。 Class /*** Copyright (C) 2020-${YEAR}, Glodon Digital Supplier & Purchaser BU.* * All Rights Reserved.*/ #if (${PACKA…

基于SSM+Jsp的旅游景点线路网站

开发语言&#xff1a;Java框架&#xff1a;ssm技术&#xff1a;JSPJDK版本&#xff1a;JDK1.8服务器&#xff1a;tomcat7数据库&#xff1a;mysql 5.7&#xff08;一定要5.7版本&#xff09;数据库工具&#xff1a;Navicat11开发软件&#xff1a;eclipse/myeclipse/ideaMaven包…

在线求助:什么!!我的单链表只能得30分!!

题目&#xff1a; 来源&#xff1a; B3631 单向链表 - 洛谷 | 计算机科学教育新生态 (luogu.com.cn) 我的代码 输入输出&#xff1a; 输入 6 1 1 99 1 99 50 1 99 75 2 99 3 75 2 1 输出 75 99 我的测试结果&#xff1a;

JAVA---类和对象详解(1)

JAVA类和对象详解(1) 1.面向对象的初步认知 1.1什么是面向对象? Java是一门纯面向对象的语言(Object Oriented Program&#xff0c;简称OOP)&#xff0c;在面向对象的世界里&#xff0c;一切皆为对象。面向对象是解决问题的一种思想&#xff0c;主要依靠对象之间的交互完成…

VSCode的maven插件配置问题

最近尝试使用VSCode开发java后台项目&#xff0c;发现安装了java开发套件的插件 配置了开发环境之后&#xff0c;maven下载的依赖包始终位于~/.m2/repository目录之后&#xff0c;放在了默认的C盘&#xff0c;这就是我最不喜欢的位置。 为了保证C的小&#xff0c;所以需要修改…

物联网工程的未来发展趋势及影响

物联网工程是在互联网基础上的一种新兴技术&#xff0c;其核心思想是通过网络连接不同物体&#xff0c;实现智能化的交流与互动。在未来&#xff0c;物联网工程将继续向更多领域发展&#xff0c;如智能家居、智能城市、智能交通等。首先&#xff0c;物联网工程在智能家居领域的…

《Windows API每日一练》4.3 点和线的绘制

理论上&#xff0c;所有的图形设备驱动程序所需要的就是SetPixel函数和GetPixel函数。其余的一切都可以使用在GDI模块中实现的更高层的例程来处理。例如&#xff0c;画一条线&#xff0c;GDI可以不停地调整x和y坐标&#xff0c;然后连续调用多次SetPixel函数来实现。 事实上&a…

[vue3]组件通信

自定义属性 父组件中给子组件绑定属性, 传递数据给子组件, 子组件通过props选项接收数据 props传递的数据, 在模版中可以直接使用{{ message }}, 在逻辑中使用props.message defineProps defineProps是编译器宏函数, 就是一个编译阶段的标识, 实际编译器解析时, 遇到后会进行…

LogicFlow 学习笔记——9. LogicFlow 进阶 节点

LogicFlow 进阶 节点&#xff08;Node&#xff09; 连线规则 在某些时候&#xff0c;我们可能需要控制边的连接方式&#xff0c;比如开始节点不能被其他节点连接、结束节点不能连接其他节点、用户节点后面必须是判断节点等&#xff0c;想要达到这种效果&#xff0c;我们需要为…

腾讯地图避坑-获取地图点击点的经纬度

map.on(click,(evt)>{console.log("evt",evt)let lat evt.latLng.getLat();//lat 获取let lng evt.latLng.getLng();//lng 获取console.log("evt.latLng-有效方式",evt.latLng)console.log("evt[latlng]-无效方式",evt[latlng])})

docker容器基本原理简介

一、docker容器实例运行的在linux上是一个进程 1&#xff09;、我们通过docker run 通过镜像运行启动的在linux上其实是一个进程&#xff0c;例如我们通过命令运行一个redis&#xff1a; docker run -d --name myredis redis2&#xff09;、可以看到首先我们本地还没有redis镜…

WPS如何合并多个word文档到一个文档中

将多个Word文档合并成一个 【插入】---》【附件】----》【文件中的文字】----》选择多个需要合并的word文档&#xff0c;点击确定即可。 用的工具是WPS。

12c rac到单机adg开启同步报错ora-01157 ora-01110 temp文件相关错误

问题 处理方法 alter database recover managed standby database cancel; create temporary tablespace TEMP1 tempfile /u01/app/oracle/oradata/standby/temp_01.dbf size 10240m autoextend on; SQL> alter database recover managed standby database disconnect fr…

蜂鸣器(2):12V有源蜂鸣器

蜂鸣器&#xff08;2&#xff09;&#xff1a;12V有源蜂鸣器 在本教程中&#xff0c;我们将学习如何对Arduino进行编程&#xff0c;以控制12V有源蜂鸣器以产生响亮的声音。如果您想控制 5V 有源/无源蜂鸣器&#xff0c;请查看此 Arduino 压电蜂鸣器教程 Hardware Required 所…