算法思想总结:位运算

                                               创作不易,感谢三连支持!!

一、常见的位运算总结

标题

 

 

二、位1的个数

. - 力扣(LeetCode)

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

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

 三、汉明距离

. - 力扣(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;
    }
};

 四、比特数记位(典型dp)

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

class Solution {
public:
   int countOnes(int x)
   {
    int ones=0;
    while(x)
    {
        x&=(x-1);
        ++ones;
    }
    return ones;
   }
    //利用
    vector<int> countBits(int n) 
    {
       vector<int> ret(n+1);
       for(int i=1;i<=n;++i)  ret[i]=countOnes(i);
       return ret;
    }
};

 思路2:动态规划思想(本质是根据位运算的性质通过已经计算出来的状态去求未计算的状态)

         即当计算 i 的「一比特数」时,如果存在 0≤j<i,j 的「一比特数」已知,且 i和 j 相比,i 的二进制表示只比j多了一个 1,则可以快速得到 i 的「一比特数」。(利用位运算的性质)

1、设置最低位

        对于n(n-1),本质上是将最右侧的1干掉,所以一定会比原来的n小!!

因此bit[i]=bit[i&(i-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、最低有效位

      对于正整数x来说,如果是偶数的话,右移一位正好就是x/2,并且1的个数不会变,所以偶数bit[i]=bit[i/2]   对于奇数来说,右移一位会丢掉后面的1,所以要给他补上去,所以奇数等于bit[i]=bit[i/2]+1       为了修正奇数多出来的1,我们可以利用i&1,如果是奇数就是1,偶数就是0,因此   bit[i]=bit[i/2]+(i&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/2]+(i&1);
       return ret;
    }
};

3、最高有效位

       对于正整数 x,如果可以知道最大的正整数 y,使得 y≤x,y 是 2的整数次幂,则 y的二进制表示中只有最高位是 1,其余都是 0,此时称 y 为 x 的「最高有效位」。令 z=x−y,显然 0≤z<x,则 bits[x]=bits[z]+1,所以我们使用heightbit作为当前的最高有效位。如果i&(i-1)为最高有效位,就更新heightbit,i 比 i−highBit的「一比特数」多 1    所以bit[i]=bit[i-height]+1 恒成立!!

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

五、只出现一次的数字(1)

. - 力扣(LeetCode)

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

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

六、只出现一次的数字(2) 

. - 力扣(LeetCode)

class Solution {
public:
    int singleNumber(vector<int>& nums) 
    {
        int ret=0;
        for(int i=0;i<32;++i)
        {
            int sum=0;
            for(int num:nums)  if((num>>i)&1) ++sum;//统计个数每一个1的比特位
            sum%=3;//模3后代表ret当前bit位的值
            if(sum==1) ret|=(1<<i);//sum==1就让ret该位置变成1
        }
        return ret;
    }
};

七、只出现一次的数字(3)

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) type1^=num; else type2^=num;
       return {type1,type2};
    }
};

八、丢失的数字

. - 力扣(LeetCode)

思路1:利用等差数列和的公式-数组每一位数相加,即可得到消失的数

class Solution {
public:
    int missingNumber(vector<int>& nums) 
    {
        int n=nums.size();
        return n*(n+1)/2-accumulate(nums.begin(),nums.end(),0);
    }
};

 思路2:利用异或的特点,让0和数组所有数进行异或,再对1-n异或,出现两次的数都会被消去,最后只会留下答案

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

思路3:暴力快排+寻找下标和数字对应不上的数 

class Solution {
public:
    int missingNumber(vector<int>& nums) 
    {
        sort(nums.begin(),nums.end());
        int n=nums.size();
        for(int i=0;i<n;++i) if(nums[i]!=i) return i;
        return n;
    }
};

九、消失的两个数字

. - 力扣(LeetCode)

该题就是只出现一次数组(1)和 (3)的结合,所以以上的思路去解答即可

class Solution {
public:
    vector<int> missingTwo(vector<int>& nums) 
    {
      int temp=0;
      for(auto e:nums) temp^=e;
      for(int i=1;i<=nums.size()+2;++i) temp^=i;
      int x=temp&(-temp);//拿到最右边的1
      int num1=0,num2=0;
      for(auto e:nums) if(e&x) num1^=e;  else  num2^=e;
      for(int i=1;i<=nums.size()+2;++i) if(i&x) num1^=i;  else  num2^=i;
      return {num1,num2};
    }
};

十、判定字符是否唯一

. - 力扣(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;//先判断该字符是否出现过 判断第i位是否是1
        //如果没出现过,将第i位的0修改为1
        bitmap|=(1<<i);
       }
       return true;
    }
};

十一、或运算的最小翻转次数

. - 力扣(LeetCode)

class Solution {
public:
    int minFlips(int a, int b, int c) 
    {
        int ret=0;//记录翻转次数
      for(int i=0;i<31;++i)
      {
        //找到每一位进行判断
        int bit_a=(a>>i)&1;
        int bit_b=(b>>i)&1;
        int bit_c=(c>>i)&1;
        //情况1,如果c为0的话,那么a和b必须全是0 所以他们是多少就要翻转几次
        if(bit_c==0) ret+=(bit_a+bit_b);
        //情况2,如果c为1的话,那么a和b至少要有一个为1    如果都为0,翻转一次,如果有1就不用翻转
        else ret+=(bit_a+bit_b==0);
      }
      return ret;
    }
};

十二、两整数之和

. - 力扣(LeetCode)

class Solution {
public:
    int getSum(int a, int b) 
    {
       //要考虑-1,因为-1的右移操作是没有定义的
       while(b)
       {
        int  x=a^b;
        int carry=(a&b)<<1;
        a=x;
        b=carry;
       }
       return a;
    }
};

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

如若内容造成侵权/违法违规/事实不符,请联系我们进行投诉反馈qq邮箱809451989@qq.com,一经查实,立即删除!

相关文章

MySQL数据库的下载和安装以及命令行语法学习

MySQL数据库的下载和安装以及命令行语法学习 学习MYSQL&#xff0c;掌握住基础的SQL句型&#xff08;创建数据库、查看数据库列表、数据增、删、改、查等操作类型&#xff09; 首先要知道MySQL下载和安装方法&#xff1a; 提示&#xff1a;别嫌啰嗦&#xff0c;对于一个初识MY…

vue-cli3中拉取vue-cli2

vue-cli3中拉取vue-cli2 拉取 2.x 模板 (旧版本) Vue CLI > 3 和旧版使用了相同的 vue 命令&#xff0c;所以 Vue CLI 2 (vue-cli) 被覆盖了。如果你仍然需要使用旧版本的 vue init 功能&#xff0c;你可以全局安装一个桥接工具&#xff1a; npm install -g vue/cli-init…

linux源配置:ubuntu、centos;lspci与lsmod命令区别

1、ubuntu源配置 1&#xff09;先查电脑版本型号: lsb_release -c2&#xff09;再编辑源更新&#xff0c;源要与上面型号对应 参考&#xff1a;https://midoq.github.io/2022/05/30/Ubuntu20-04%E6%9B%B4%E6%8D%A2%E5%9B%BD%E5%86%85%E9%95%9C%E5%83%8F%E6%BA%90/ /etc/apt/…

MUNIK第二届功能安全及自动驾驶研讨会将在沪召开

2024年4月26日,由上海秒尼科技术服务有限公司(以下简称“Munik”)联合Parosoft主办的“第二届功能安全及自动驾驶研讨会”将在上海虹桥隆重开幕。 据了解,本次功能与自动驾驶安全研讨会,将聚焦在ISO 26262标准体系下,自动驾驶新形势下各个零部件供应商如何满足功能安全等相关重…

移除和替换任何内容:AI 驱动的图像修复工具 | 开源日报 No.204

Sanster/IOPaint Stars: 15.1k License: Apache-2.0 IOPaint 是一款由 SOTA AI 模型驱动的图像修复工具。 该项目解决了从图片中移除任何不需要的对象、瑕疵或人物&#xff0c;以及擦除和替换图片上任何内容&#xff08;由稳定扩散技术支持&#xff09;的问题。 完全免费且开…

赋能数据收集:从机票网站提取特价优惠的JavaScript技巧

背景介绍 在这个信息时代&#xff0c;数据的收集和分析对于旅游行业至关重要。在竞争激烈的市场中&#xff0c;实时获取最新的机票特价信息能够为旅行者和旅游企业带来巨大的优势。 随着机票价格的频繁波动&#xff0c;以及航空公司和旅行网站不断推出的限时特价优惠&#xff…

【Java - 框架 - HttpClient 5】(01) HttpClient 5 使用详细教程,代码示例 - 快速上手

HttpClient 5 使用详细教程&#xff0c;代码示例 - 快速上手 依赖 【Maven依赖】 <!-- https://mvnrepository.com/artifact/org.apache.httpcomponents.client5/httpclient5 --> <dependency><groupId>org.apache.httpcomponents.client5</groupId>…

网络分析(蓝桥杯,acwing,并查集)

题目描述&#xff1a; 小明正在做一个网络实验。 他设置了 n 台电脑&#xff0c;称为节点&#xff0c;用于收发和存储数据。 初始时&#xff0c;所有节点都是独立的&#xff0c;不存在任何连接。 小明可以通过网线将两个节点连接起来&#xff0c;连接后两个节点就可以互相通…

JAVAEE——多线程的设计模式,生产消费模型,阻塞队列

文章目录 多线程设计模式什么是设计模式单例模式饿汉模式懒汉模式线程安全问题懒汉模式就一定安全吗&#xff1f;锁引发的效率问题jvm的优化引起的安全问题 阻塞队列阻塞队列是什么&#xff1f;生产消费者模型阻塞队列实现消费生产者模型可能遇到的异常 多线程设计模式 什么是…

【PHP + 代码审计】数组函数

&#x1f36c; 博主介绍&#x1f468;‍&#x1f393; 博主介绍&#xff1a;大家好&#xff0c;我是 hacker-routing &#xff0c;很高兴认识大家~ ✨主攻领域&#xff1a;【渗透领域】【应急响应】 【Java、PHP】 【VulnHub靶场复现】【面试分析】 &#x1f389;点赞➕评论➕收…

安全工具介绍 SCNR/Arachni

关于SCNR 原来叫Arachni 是开源的&#xff0c;现在是SCNR&#xff0c;商用工具了 可试用一个月 Arachni Web Application Security Scanner Framework 看名字就知道了&#xff0c;针对web app 的安全工具&#xff0c;DASTIAST吧 安装 安装之前先 sudo apt-get update sudo…

力扣面试150 阶乘后的零 数论 找规律 质因数

Problem: 172. 阶乘后的零 思路 &#x1f468;‍&#x1f3eb; 大佬神解 一个数末尾有多少个 0 &#xff0c;取决于这个数 有多少个因子 10而 10 可以分解出质因子 2 和 5而在阶乘种&#xff0c;2 的倍数会比 5 的倍数多&#xff0c;换而言之&#xff0c;每一个 5 都会找到一…

AWTK T9 输入法实现原理

1. T9 输入法的中文字典数据 网上可以找到 T9 输入法的中文字典数据&#xff0c;但是通常有两个问题&#xff1a; 采用 GPL 协议&#xff0c;不太适合加入 AWTK。 只支持单个汉字的输入&#xff0c;不支持词组的输入。 经过考虑之后&#xff0c;决定自己生成 T9 输入法的中…

选择器加练习

一、常用的选择器 1.元素选择器 语法 : 标签名{} 作用 : 选中对应标签中的内容 例:p{} , div{} , span{} , ol{} , ul{} ...... 2.类选择器(class选择器) 语法 : .class属性值{} 作用 : 选中对应class属性值的元素 注意:class里面的属性值不能以数字开头,如果以符号开头,…

基于python+vue城市交通管理系统的设计与实现flask-django-php-nodejs

此系统设计主要采用的是python语言来进行开发&#xff0c;采用django/flask框架技术&#xff0c;框架分为三层&#xff0c;分别是控制层Controller&#xff0c;业务处理层Service&#xff0c;持久层dao&#xff0c;能够采用多层次管理开发&#xff0c;对于各个模块设计制作有一…

Docker 镜像仓库

目录 1、搭建私有 registry 服务端创建镜像仓库 客户端推送镜像 镜像导入导出 2、Nginx 代理 registry 仓库 SSL 证书 & https 协议 SSL证书 https协议 SSL 的验证流程 客户端安装 Nginx 使用 openssl 生成CA根证书和根证书key 创建 Nginx 服务证书 配置启动 N…

线段树和树状数组

&#x1f4df;作者主页&#xff1a;慢热的陕西人 &#x1f334;专栏链接&#xff1a;力扣刷题日记 &#x1f4e3;欢迎各位大佬&#x1f44d;点赞&#x1f525;关注&#x1f693;收藏&#xff0c;&#x1f349;留言 文章目录 树状数组和线段树1.树状数组1.1动态求连续区间和1.2数…

c#矩阵求逆

目录 一、矩阵求逆的数学方法 1、伴随矩阵法 2、初等变换法 3、分块矩阵法 4、定义法 二、矩阵求逆C#代码 1、伴随矩阵法求指定3*3阶数矩阵的逆矩阵 &#xff08;1&#xff09;伴随矩阵数学方法 &#xff08;2&#xff09;代码 &#xff08;3&#xff09;计算 2、对…

Unity Shader

练习项目链接 1. Shader 介绍 Shader其实就是专门用来渲染图形的一段代码&#xff0c;通过shader&#xff0c;可以自定义显卡渲染画面的算法&#xff0c;使画面达到我们想要的效果。小到每一个像素点&#xff0c;大到整个屏幕&#xff0c;比如下面这个比较常见的效果。 2. Sh…

javaSwing宿舍管理系统(三个角色)

一、 简介 宿舍管理系统是一个针对学校宿舍管理的软件系统&#xff0c;旨在方便学生、宿管和管理员进行宿舍信息管理、学生信息管理以及宿舍评比等操作。该系统使用 Java Swing 进行界面设计&#xff0c;分为三个角色&#xff1a;管理员、宿管和学生。 二、 功能模块 2.1 管…