【练习】位运算思想

  • 🎥 个人主页:Dikz12
  • 🔥个人专栏:算法(Java)
  • 📕格言:吾愚多不敏,而愿加学
  • 欢迎大家👍点赞✍评论⭐收藏

目录

1.判断字符串是否唯一 

 题目描述

讲解 

代码实现

2.丢失的数字

 题目描述

​编辑 讲解

代码实现

3.两整数之和

题目描述 

 讲解

代码实现

4.只出现一次的数字II

题目描述

 讲解

 代码实现

5.消失的两个数字 

题目描述 

讲解 

代码实现 

常见位运算总结  

基础位运算

给一个数n,确定它的二进制表示中的第x位是0还是1.

将一个数n 的二进制表示的第x位修改成1

将一个数n的二进制表示的第x位修改成0

位图思想  

异或运算规律 


1.判断字符串是否唯一 

 题目描述

讲解 

解法一:使用哈希表(只有小写字母可用数组模拟)

解法二:位运算(位图思想).

利⽤「位图」的思想,每⼀个⽐特位 代表⼀个 字符,⼀个 int 类型的变量的 32 位⾜够;
表⽰所有的⼩写字⺟。⽐特位⾥⾯如果是 0 ,表⽰这个字符没有出现过。⽐特位⾥⾯的值是 1
表⽰该字符出现过

代码实现

    public boolean isUnique(String astr) {
        if(astr.length() > 26) {
            return false;
        }
        int bitMap = 0;
        for(int i = 0; i < astr.length(); i++) {
            int x = astr.charAt(i) - 'a';
            if(((bitMap >> x) & 1) == 1) {
                return false;
            }
            //添加字符
            bitMap |= 1 << x;
        }
        return true;
    }

2.丢失的数字

 题目描述

 讲解

解法一: 模拟哈希数组

解法二:高斯求和(推荐) 

解法三:异或运算. (推荐)

把数组中的所有数,以及 [0, n] 中的所有数全部「异或」在⼀起,那么根据「异或」
运算的「消消乐」规律,最终的异或结果应该就是缺失的数.

代码实现

    public int missingNumber(int[] nums) {
        int ret = 0;
        for(int i = 0; i < nums.length; i++) {
            ret ^= nums[i];
        }
        for(int i = 0; i <= nums.length; i++) {
            ret ^= i;
        }
        return ret;
    }

3.两整数之和

题目描述 

 讲解

解法一:return a+b;(开个玩笑) .

这里要求不使用运算符"+"、"-",所以,也就只能使用位运算了.

解法二:位运算.

  • 异或 ^ 运算本质是:⽆进位加法
  • 按位与 & 操作能够得到进位
  • 然后⼀直循环进⾏,直到 进位变成 0 为⽌

代码实现

    public int getSum(int a, int b) {
        while(b != 0) {
            int ret = a ^ b;
            int carry = (a & b) << 1;
            a = ret;
            b = carry;
        }
        return a;
    }

4.只出现一次的数字II

题目描述

 讲解

  1. 根据所有数的某⼀个⽐特位的总和 %3 的结果,快速定位到 ret 的⼀个⽐特位上的值是 0 还是 1
  2. 通过 ret 的每⼀个⽐特位上的值,就可以将 ret 给还原出来.

 代码实现

    public int singleNumber(int[] nums) {
        int ret = 0;
        for(int i = 0; i < 32; i++) {
            //统计比特位个数
            int sum = 0;
            for(int x : nums) {
                if(((x >> i) & 1) == 1) {
                    sum++;
                }
            }
            if(sum % 3 != 0) {
                //修改比特位
                ret |= 1 << i;
            }
        }
        return ret;
    }

5.消失的两个数字 

题目描述 

讲解 

  1.  将所有的数异或在一起 => 丢失的数字(ret = a^b)
  2. 找到 ret中,比特位 x 为 1 的那一位
  3. 根据 x位的不同,划分成两类异或.

代码实现 

    public int[] missingTwo(int[] nums) {
        // 1.将所有的数异或在一起
        int tmp = 0;
        for(int i = 0; i < nums.length; i++) {
            tmp ^= nums[i];
        }
        for(int i = 1; i <= nums.length + 2; i++) {
            tmp ^= i;
        }
        //2.找出tmp中,比特位为一的那一位 tmp = a ^ b
        int index = 0;
        while(true) {
            if(((tmp >> index) & 1) == 1) {
                break;
            }else{
               index++;
            } 
        }
        // 3.根据index位不同,分为两类异或
        int[] ret = new int[2];
        for(int x : nums) {
            if(((x >> index) & 1) == 1) {
                ret[1] ^= x;
            }else{
                ret[0] ^= x;
            }
        }
        for(int i = 1; i <= nums.length + 2; i++) {
               if(((i >> index) & 1) == 1) {
                ret[1] ^= i;
            }else{
                ret[0] ^= i;
            }
        }
        return ret;
    }

常见位运算总结  

基础位运算

&(按位与):有0就是0;

| (按位或):有 1 就是 1;

^ (按位异或):相同为0,相异为1 / 无进位相加;

>> 、<<、~ (右移、左移、按位取反)这几个就比较简单了,就不在说明了。

给一个数n,确定它的二进制表示中的第x位是0还是1.

将一个数n 的二进制表示的第x位修改成1

将一个数n的二进制表示的第x位修改成0

 

位图思想  

异或运算规律 

  • 75
    点赞
  • 59
    收藏
    觉得还不错? 一键收藏
  • 49
    评论
评论 49
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值