Java优选算法之位运算实战例子

 更新时间:2025年11月15日 10:41:29   作者:iナナ  
这篇文章主要介绍了Java优选算法之位运算的相关资料,位运算基础包括左移、右移、取反、按位与、按位或、异或等操作,文中通过代码介绍的非常详细,需要的朋友可以参考下

常见位运算总结

1.基础位运算

<<:表示左移

>>:表示右移

~:表示每一位取反

&:表示“且”,有0则0

|:表示“或”,有1则1

^:异或操作,相同为0,相异为1(无进位相加)

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

计算(n>>x)&1

  • 为1:第x位是1
  • 为0:第x位是0

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

n=n|(1<<x)

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

n=n&(~(1<<x))

5.提取一个数n二进制表示中最右侧的1

只提取出最右边的1,说明左边的可以不要(为0)

n&-n

6.去掉一个数n二进制表示中最右侧的1

只去掉最右边的1,说明左边的不变

n&(n-1)

一、判断字符是否唯一

题目链接:https://leetcode.cn/problems/is-unique-lcci/description/

题目:

实现一个算法,确定一个字符串 s 的所有字符是否全都不同。

示例 1:输入:s = "leetcode"输出:false

示例 2:输入:s = "abc"输出:true

限制:

  • 0<=len(s)<=100
  • s [i] 仅包含小写字母
  • 如果你不使用额外的数据结构,会很加分。

思路:

这道题使用了位图的思想。

我们需要一个数bitmap=0,让它的每一个二进制位的数字来表示字母是否出现过。

首先:如果字符串的长度大于26,那必定有重复的字符出现。

当我们遍历字符串时,拿出对应的字符找到在位图中对应的位置,判断该位置是否为1,如果为1,说明这个字符串是重复了的,返回false;如果为0,则将位图中对应的位置修改为1,直到遍历完整个字符串。

代码及结果:

class Solution {
    public boolean isUnique(String astr) {
        if(astr.length()>26) return false;
        int bitmap=0;//建立一个位图,有32位
        //对应字符位置的元素为1,则说明有该字符
        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;
    }
}

二、

题目链接:https://leetcode.cn/problems/missing-number/

题目:

给定一个包含 [0,n] 中 n 个数的数组 nums,找出 [0,n] 这个范围内没有出现在数组中的那个数。

示例 1:

输入:nums=[3,0,1]

输出:2

解释:n=3,因为有 3 个数字,所以所有的数字都在范围 [0,3] 内。2 是丢失的数字,因为它没有出现在 nums中。

示例 2:

输入:nums=[0,1]

输出:2

解释:n=2,因为有 2 个数字,所以所有的数字都在范围 [0,2] 内。2 是丢失的数字,因为它没有出现在 nums中。

示例 3:

输入:nums=[9,6,4,2,3,5,7,0,1]

输出:8

解释:n=9,因为有 9 个数字,所以所有的数字都在范围 [0,9] 内。8 是丢失的数字,因为它没有出现在 nums中。

思路:

使用位运算中的异或运算(无进位相加)。

把数组中所有元素异或起来,再将0~n的所有数也异或起来,就能两两消除相同的数。

代码及结果:

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

三、两整数之和

题目链接:https://leetcode.cn/problems/sum-of-two-integers/

题目:

给你两个整数 a 和 b,不使用运算符 + 和 -,计算并返回两整数之和。

示例 1:输入:a = 1,b = 2输出:3

示例 2:输入:a = 2,b = 3输出:5

思路:

本题要求不能使用运算符,所以使用位运算解决。

首先,使用无进位相加a^b,

至于进位操作:在异或结果的基础上找出哪些是需要进位的(a&b)<<1,

将a^b作为新的a,将(a&b)<<1作为新的b,继续重复以上操作,直到不需要进位,即b为0。

代码及结果:

class Solution {
    public int getSum(int a, int b) {
        while(b!=0){
            int x=a^b;//先计算出a和b无进位相加结果
            b=(a&b)<<1;
            a=x;
        }
        return a;
    }
}

四、只出现一次的数字Ⅱ

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

题目:

给你一个整数数组 nums,除某个元素仅出现一次外,其余每个元素都恰出现三次。请你找出并返回那个只出现了一次的元素。

你必须设计并实现线性时间复杂度的算法且使用常数级空间来解决此问题。

示例 1:输入:nums = [2,2,3,2]输出:3

示例 2:输入:nums = [0,1,0,1,0,1,99]输出:99

思路:

除目标数外,每一个数的二进制的每一位要么为0要么为1,则所有数的对应的二进制位数相加,应该为3n个0或者3n个1(n表示整数),将其与目标数的对应二进制位相加后%3:

当结果为0,则目标数该位数为0;

当结果为1,则目标数该位数为1;

代码及结果:

class Solution {
    public int singleNumber(int[] nums) {
        int ret=0;//要查找的那个数字
        for(int i=0;i<32;i++){//依次遍历位图的每一位
            int sum=0;//用于存放所有数字第i位之和
            for(int x:nums){
                if(((x>>i)&1)==1){
                    sum++;
                }
            }
            ret=ret^((sum%3)<<i);
        }
        return ret;
    }
}

五、消失的两个数字

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

题目:

给定一个数组,包含从 1 到 N 所有的整数,但其中缺了两个数字。你能在 O (N) 时间内只用 O (1) 的空间找到它们吗?

以任意顺序返回这两个数字均可。

示例 1:输入:[1]输出:[2,3]

示例 2:输入:[2,3]输出:[1,4]

思路:

这道题依旧使用位运算的思想,我们将数组和1~N之间的数都异或起来,这时得到的数为x1和x2的异或。

首先x1和x2一定不相等,所以x1和x2异或的结果的二进制位中一定有“1”,假设1在第x位,则x1在x位的数是与x2的不同的。

假设x1在x位为0,x2在x位为1,我们再将所有的数分为两类:

一类在x位为0,它们异或之后结果就为x1;

一类在x位为1,它们异或之后结果就为x2.

代码及结果:

class Solution {
    public int[] missingTwo(int[] nums) {
        int ans[]=new int[2];
        //转化为:只出现一次的数字3
        int ret=0;//存放x1^x2
        int n=nums.length;
        for(int x:nums){
            ret^=x;
        }
        for(int i=1;i<=n+2;i++){
            ret^=i;
        }
        //此时ret=x1^x2;

        //在nums中和1到N的所有数中找到x1和x2
        //1 先找到ret中最右边的1所在位置
        ret=ret&(-ret);
        int x1=0,x2=0;
        //说明x1和x2在这个位置的值不一样,假如x1此处为0,x2此处为1
        for(int x:nums){
            if((x&ret)==0){//说明x在这个位置的数为0,与x1分为一类
                x1^=x;
            }else{
                x2^=x;
            }
        }
        for(int i=1;i<=n+2;i++){
            if((i&ret)==0){//说明x在这个位置的数为0,与x1分为一类
                x1^=i;
            }else{
                x2^=i;
            }
        }
        ans[0]=x1;
        ans[1]=x2;
        return ans;
    }
}

总结 

到此这篇关于Java优选算法之位运算的文章就介绍到这了,更多相关Java位运算内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • Java实现的3des加密解密工具类示例

    Java实现的3des加密解密工具类示例

    这篇文章主要介绍了Java实现的3des加密解密工具类,结合完整实例形式分析了3des加密解密的具体步骤与相关操作技巧,需要的朋友可以参考下
    2017-10-10
  • shiro整合springboot前后端分离

    shiro整合springboot前后端分离

    这篇文章主要介绍了shiro整合springboot前后端分离,文中示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2019-12-12
  • Java异常 Exception类及其子类(实例讲解)

    Java异常 Exception类及其子类(实例讲解)

    下面小编就为大家带来一篇Java异常 Exception类及其子类(实例讲解)。小编觉得挺不错的,现在就分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2017-11-11
  • Spring HTTP缓存应用场景举例

    Spring HTTP缓存应用场景举例

    这篇文章详细介绍了Spring Framework中HTTP缓存的基本概念和实现方式,包括Cache-Control头、条件请求(ETag/Last-Modified)、CacheControl类的使用,以及在控制器和静态资源中应用HTTP缓存,本文结合实例代码给大家介绍的非常详细,感兴趣的朋友一起看看吧
    2025-11-11
  • Spring boot怎么整合Mybatis

    Spring boot怎么整合Mybatis

    spring boot的简配置方便的开发,下面通过本文给大家分享Spring boot整合Mybatis的方法,需要的朋友参考下
    2017-07-07
  • Springboot @Import 详解

    Springboot @Import 详解

    这篇文章主要介绍了Springboot @Import 详解,仔细看了下Springboot关于@Import的处理过程,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-11-11
  • Java IO和NIO的基本概念和API详解

    Java IO和NIO的基本概念和API详解

    JavaIO是基于流的阻塞式I/O,适用于低并发场景;JavaNIO是基于通道和缓冲区的非阻塞式I/O,适用于高并发场景
    2025-03-03
  • Java中实现线程的三种方式及对比_动力节点Java学院整理

    Java中实现线程的三种方式及对比_动力节点Java学院整理

    本文给大家分享了java实现线程的三种方式,非常不错,具有参考借鉴价值,需要的朋友参考下吧
    2017-05-05
  • Springboot3整合Mybatis-plus3.5.3报错问题解决

    Springboot3整合Mybatis-plus3.5.3报错问题解决

    在日常学习springboot3相关的代码时,在使用 SpringBoot3 整合 MyBatisplus 时出现了一些问题,花了不少时间处理,这篇文章主要介绍了Springboot3整合Mybatis-plus3.5.3报错问题解决,需要的朋友可以参考下
    2023-11-11
  • Java for循环常见优化方法案例详解

    Java for循环常见优化方法案例详解

    这篇文章主要介绍了Java for循环常见优化方法案例详解,本篇文章通过简要的案例,讲解了该项技术的了解与使用,以下就是详细内容,需要的朋友可以参考下
    2021-08-08

最新评论