【Java算法专场】位运算(上)

news2024/9/24 22:37:07

目录

常见位运算总结

位1的个数

算法思路

算法代码

比特位计数

算法思路

算法代码

汉明距离

算法思路

算法代码

只出现一次的数字

算法思路

算法代码

丢失的数字

算法思路

算法代码


 

常见位运算总结

 

 

 

 了解位运算的一些基本操作,那么我们就来通过题目来巩固一下

位1的个数

算法思路

  1. 初始化:定义变量count来存储变量比特位1的个数。
  2. 遍历:利用上述第7条特性。当遍历不为0时,循环遍历,每次让变量按位与(n-1),干掉最右侧的1,让count++.
  3. 返回结果:当遍历完成,返回count即可。

算法代码

/**
 * Solution类提供了一种计算整数的汉明重量的方法
 * 汉明重量是整数在二进制表示中1的个数
 */
class Solution {
    /**
     * 计算给定整数的汉明重量
     * 
     * @param n 整数输入,其汉明重量将被计算
     * @return 返回n的汉明重量
     */
    public int hammingWeight(int n) {
        // 初始化计数器为0,用于记录汉明重量
        int count=0;
        // 当n不为0时,循环继续
        while(n!=0){
            // 使用n和n-1进行位操作,消除n二进制表示中的最后一个1
            n&=(n-1);
            // 每消除一个1,计数器增加1
            count++;
        }
        // 返回计数器的值,即汉明重量
        return count;
    }
}

时间复杂度为O(logn).

比特位计数

算法思路

  1. 初始化:定义一个长度为n+1的数组ans,用来存储结果。
  2. 计数方法:我们可以利用特性7n&(n-1),来计算一个数二进制有多少个1,并利用变量ones来计数。
  3. 循环:从1开始遍历到n,每次循环都调用计数方法并将i传过去,将返回值放入到ans[i]中
  4. 返回ans:当遍历完成之后,返回ans数组即可。 

算法代码

/**
 * Solution类提供了一种计算从0到给定数字n之间每个数字二进制表示中1的数量的方法
 */
class Solution {
    /**
     * 计算从0到n每个数字的二进制表示中1的数量
     * 
     * @param n 需要计算的范围上限
     * @return 一个整数数组,其中数组的第i个元素表示数字i的二进制表示中1的数量
     */
    public int[] countBits(int n) {
        // 初始化答案数组,大小为n+1,以便包含从0到n的所有数字
        int[] ans = new int[n + 1];
        // 遍历从1到n的每个数字,计算并存储每个数字二进制表示中1的数量
        for (int i = 1; i <= n; i++) {
            ans[i] = countOne(i);
        }
        return ans;
    }

    /**
     * 计算给定数字x的二进制表示中1的数量
     * 
     * @param x 需要计算的数字
     * @return 返回x的二进制表示中1的数量
     */
    public int countOne(int x) {
        // 初始化计数器,用于记录1的数量
        int one = 0;
        // 循环直到x为0,每次迭代都会消除x二进制表示中最右侧的1
        while (x != 0) {
            // 使用位操作消除最右侧的1,位运算的结果将x的最右侧的1变为0
            x &= (x - 1);
            // 增加计数器,表示已经消除一个1
            one++;
        }
        // 返回计数器的值,即x二进制表示中1的总数
        return one;
    }
}

时间复杂度为O(n*logx),n为数组长度,x为数组元素值。

空间复杂度为O(n) 

汉明距离

算法思路

  1. 初始化:定义变量n,并初始化为x^y,定义count并初始化为0,用来计算n的1的个数。

  2. 循环:当n不为0 时,通过特性7n&(n-1),每次干掉n最右侧的1,并让count++.

  3. 返回:当结束循环后,此时返回count即可。

算法代码

/**
 * Solution类提供了一个方法来计算两个整数之间的汉明距离
 * 汉明距离是指两个数的二进制表示中,不同位的数量
 */
class Solution {
    /**
     * 计算两个整数x和y之间的汉明距离
     * 
     * @param x 第一个整数
     * @param y 第二个整数
     * @return 返回x和y之间的汉明距离
     */
    public int hammingDistance(int x, int y) {
        // 通过异或操作找出x和y不同的位,结果存储在n中
        int n = x ^ y;
        int count = 0;
        // 循环直到n为0,每次循环都会将n的最后一个1变为0,并增加计数
        while (n != 0) {
            // 利用n&(n-1)将n的最后一个1变为0,并进行与操作,以计算有多少个1
            n &= (n - 1);
            count++;
        }
        // 返回计数的结果,即汉明距离
        return count;
    }
}

时间复杂度为O(logn),n为x^y的值,过程中只遍历到n二进制中1的数。

空间复杂度为O(1),只用了常数个变量。 

只出现一次的数字

 

算法思路

  1. 初始化:定义变量ans并初始化为0。

  2. 遍历数组:利用特性9,按位异或(^)数组每一个元素。

  3. 返回:当遍历完数组,返回ans即可。 

算法代码

/**
 * Solution 类,提供数组操作的解决方案。
 */

class Solution {
    /**
     * 在一个数组中找出只出现一次的数字。
     * 使用按位异或运算来消除成对出现的数字,最终剩下的就是那个唯一的数字。
     * 
     * @param nums 一个整数数组,其中每个元素除了一个之外都出现了两次。
     * @return 数组中只出现一次的那个元素。
     */
    public int singleNumber(int[] nums) {
        // 初始化答案变量为 0,因为它是异或运算的身份元素。
        int ans = 0;
        // 遍历数组并对所有元素执行异或运算。
        for (int x : nums) {
            ans ^= x;
        }
        // 返回异或运算的结果,即我们要找的答案。
        return ans;
    }
}

时间复杂度为O(n),n为数组长度

空间复杂度为O(1),只用了1个变量。 

丢失的数字

算法思路

  1. 初始化:定义一个变量ans并初始化位0,用来存储缺失的数。

  2. 遍历:这里需要遍历两次,第一次从0遍历到n,遍历过程中ans^=i,第二次遍历数组中的元素,ans同样是ans^=nums[i]。

  3. 返回结果:当遍历完成之后,返回结果ans即可。 

算法代码

/**
 * Solution类用于解决寻找缺失数字的问题
 */
class Solution {
    /**
     * 使用异或操作查找缺失的数字
     * 该方法通过将数组中的每个元素与从0到n的每个数字进行异或操作,来找到缺失的数字
     * 异或操作具有自反性和交换律,因此所有数字都会被取消,除了那个缺失的数字
     *
     * @param nums 一个包含从0到n的n个唯一数字的数组,其中一个数字缺失
     * @return 缺失的数字
     */
    public int missingNumber(int[] nums) {
        // 初始化答案为0,因为异或操作需要一个起始值
        int ans = 0;
        // 获取数组长度,即n
        int n = nums.length;
        // 对数组中的每个元素进行异或操作
        for (int i = 0; i < n; i++) {
            ans ^= nums[i];
        }
        // 对从0到n的每个数字进行异或操作,包括缺失的数字
        for (int i = 0; i <= n; i++) {
            ans ^= i;
        }
        // 返回缺失的数字
        return ans;
    }
}

 时间复杂度为O(n),n为数组长度

空间复杂度为O(1),只用了一个变量。


本篇就先到这了,下篇将讲解位运算在leetcode中的一些中等题目~

若有不足,欢迎指正~

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

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

相关文章

STM32的USB接口介绍

STM32 USB接口是STM32微控制器系列中集成的一种通信接口&#xff0c;它允许STM32微控制器与外部设备或计算机进行高速的数据传输和通信。以下是STM32 USB接口的简要介绍&#xff1a; 1. 接口类型 STM32的USB接口通常支持USB 2.0标准&#xff0c;部分高端型号可能还支持USB 3.…

新手必看!剪映轻松上手,让你的视频瞬间高大上

相信现在短视频兴起的时代下&#xff0c;几乎人手都在学习如何剪辑出日常视频&#xff0c;尤其是想要走新媒体路线的小伙伴更是在尝试专业的剪辑&#xff0c;不过平时的vlog或者抖音短视频可以从简单的开始接触&#xff0c;剪映是其中的一款适合初学者上手的剪辑了&#xff0c;…

网络编程复习

1.网络编程基础 1.1引入 socket套接字实现主机之间的通信 cs通信模型基于socket实现&#xff0c;需要客户端软件来实现通信 bs通信模型基于http实现&#xff0c;是网页通信&#xff0c;不需要任何客户端软件 1.2通信协议 &#xff08;1&#xff09;OSI七层通信协议&#xff…

QEMU理解与分析系列(1):QEMU简介

QEMU简介 一、QEMU基本介绍1.1操作模式1.2 虚拟化方式中间代码实现方式简介源码结构分布 二、qemu tcg前端解码逻辑2.1 tcg翻译流程2.1.1 decode tree语法2.1.2 trans_xxx函数的逻辑 三、编译相关3.1 代码拉取&#xff08;拉取自己想要的版本&#xff09;3.2 编译参数3.3 依赖包…

Spring Boot - 在Spring Boot中实现灵活的API版本控制(上)

文章目录 为什么需要多版本管理&#xff1f;在Spring Boot中实现多版本API的常用方法1. URL路径中包含版本号2. 请求头中包含版本号3. 自定义注解和拦截器 注意事项 为什么需要多版本管理&#xff1f; API接口的多版本管理在我们日常的开发中很重要&#xff0c;特别是当API需要…

关于Zoho mail邮箱续费、退款、升级的说明

在使用企业邮箱服务的过程中&#xff0c;可能会遇到续费&#xff0c;退款及升级服务的情况。遇到这些情况时应该如何处理&#xff1f;本文将为您提供遇到邮箱情况时的详细操作步骤&#xff1a;邮箱续费方式及续费流程、邮箱申请退款方式、邮箱升级服务的流程。 一、Zoho邮箱如…

动态面板门槛模型及 Stata 具体操作步骤

目录 一、文献综述 二、理论原理 三、实证模型 四、稳健性检验 五、程序代码及解释 六、代码运行结果 一、文献综述 动态面板门槛模型作为一种先进的计量经济学方法&#xff0c;在众多领域的研究中发挥着关键作用。在经济增长领域&#xff0c;[学者 A]通过构建动态面板门槛…

你的会议记录还用手写吗?3款免费语音转文字工具

现在&#xff0c;随着大家越来越习惯用电脑和手机工作&#xff0c;很多专业人士都在找更快捷的方法来记录会议内容。以前那种手写笔记&#xff0c;不仅写起来慢&#xff0c;而且整理和分享起来也很麻烦。幸好&#xff0c;随着科技的发展&#xff0c;出现了一些能将说话的声音直…

【计算机网络】什么是socket编程?以及相关接口详解

&#x1f490; &#x1f338; &#x1f337; &#x1f340; &#x1f339; &#x1f33b; &#x1f33a; &#x1f341; &#x1f343; &#x1f342; &#x1f33f; &#x1f344;&#x1f35d; &#x1f35b; &#x1f364; &#x1f4c3;个人主页 &#xff1a;阿然成长日记 …

letcode 分类练习 x个数之和问题 15. 三数之和 18. 四数之和 454. 四数相加 II 383. 赎金信

letcode 分类练习 x个数之和问题 15. 三数之和 18. 四数之和 454. 四数相加 II 383. 赎金信 三数之和四数之和454. 四数相加 II383. 赎金信 三数之和 三数之和&#xff0c;双指针模版代码&#xff0c;注意去重逻辑&#xff0c;还有只需要去重第一和第二重循环&#xff0c;第三…

从Python翻译Go代码谈起:AI辅助编程的现状与展望

最近&#xff0c;一位同学使用GPT-4o将一个约300行的Python程序转换成Golang&#xff0c;正确率达到了90%。这引发了一个有趣的讨论&#xff1a;如果是整个项目规模的代码转换&#xff0c;准确率会如何&#xff1f;作为被的对象&#xff0c;我决定深入探讨这个话题&#xff0c;…

高等数学精解【6】

文章目录 直线与二元一次方程直线方程斜率两点式方程截距式方程将不同形式的直线方程转换为截距方程直线的一般方程直线一般方程的系数有一个或两个为零的直线 参考文献 直线与二元一次方程 直线方程 斜率 直线对于 x 轴的倾角&#xff0c;平行于 x 轴&#xff0c;倾角为 0 &…

从一个服务预热不生效问题谈微服务无损上线

作者&#xff1a;凡问、启淮 前言 本文基于阿里云技术服务团队和产研团队&#xff0c;在解决易易互联使用 MSE&#xff08;微服务引擎&#xff09;产品无损上线功能所遇到问题的过程总结而成。本文将从问题和解决方法谈起&#xff0c;再介绍相关原理&#xff0c;后进一步拓展…

jupyter下载

https://blog.csdn.net/qq_48372575/article/details/125630622 我下面是CPU运行的&#xff0c;GPU链接在上面 Anaconda下载 https://docs.anaconda.com/miniconda/miniconda-other-installer-links/ 参考链接&#xff1a; https://blog.csdn.net/qq_48372575/article/detai…

计算机编码 - 笔记

1 ASCII码 - 0- 127 2 ASCII码扩展字符集 - 128- 255

反转字符串(LeetCode)

题目 编写一个函数&#xff0c;其作用是将输入的字符串反转过来。输入字符串以字符数组 的形式给出。 不要给另外的数组分配额外的空间&#xff0c;你必须原地修改输入数组、使用 的额外空间解决这一问题。 解题 def reverse_string(s):left 0right len(s) - 1while left …

SDF Marching Cubes Ray-marching Teahouse

SDF & Marching Cubes & Ray-marching SDF SDF(Signed Distance Field)有向距离场。SDF是由到&#xff08;多边形模型&#xff09;物体表面最近距离的采样网格。作为惯例&#xff0c;使用负值来表示物体内部&#xff0c;使用正值表示物体外部。 Marching Cubes marc…

CUDA编程05 - GPU内存架构和数据局部性

一&#xff1a;概述 到目前为止&#xff0c;我们已经学会了如何编写 CUDA 核函数&#xff0c;以及如何设置和分配大量线程来执行核函数。我们还了解了当前 GPU 硬件的计算架构&#xff0c;以及线程在硬件上调度执行过程。在本章中&#xff0c;我们将重点关注 GPU 的片上(on-chi…

golang实现Digest认证鉴权接口

什么是Digest认证鉴权接口? Digest认证鉴权接口是一种基于摘要算法的身份验证方法,用于确保API请求的安全性。在实际应用中,常常使用HTTP协议的Digest认证鉴权接口来验证请求的合法性。下面是一种常见的Digest认证鉴权流程: 1. 客户端发送HTTP请求到服务器,请求接口资源…

【MCAL】TC397+EB-tresos之ADC配置实战 - (模数转换)

本篇文章首先从理论讲起&#xff0c;基于《MC-ISAR_TC3xx_UM_Adc.pdf》介绍了ADC模块的理论知识&#xff0c;然后详细介绍了在TC397平台使用EB-tresos对ADC驱动模块进行配置与调试的实战过程&#xff0c;帮助第一次接触这个模块的读者能够更快的上手来实现符合自己项目要求的开…