算法通关村第11关【白银】| 位运算高频算法题

一、移位的妙用

1.位1的个数

思路:

利用一个数和1与操作,结果就是最低位的特点,每次右移都能知道一位是不是1

public class Solution {// you need to treat n as an unsigned valuepublic int hammingWeight(int n) {int count = 0;for(int i = 0;i<32;i++){count += (n >> i) & 1;}return count;  }
}

n-1 将最低位的 '1' 变为 '0',并将低位的 '0' 变为 '1',然后与 n 进行按位与运算,即可将最低位的 '1' 置为 '0'。这个算法的精妙之处在于,它不需要遍历所有的位,而是通过不断地将最低位的 '1' 置为0来计算 '1' 的个数,从而实现了高效的计算。这对于处理大量二进制数据的情况非常有用。

public class Solution {// you need to treat n as an unsigned valuepublic int hammingWeight(int n) {int count = 0;while((n != 0)){n = n&(n-1);count++;}return count;  }
}

2.比特位计数

思路:从0到n循环执行求位1的个数

class Solution {public int[] countBits(int n) {int[] ans = new int[n+1];for(int i = 0;i<=n;i++){int num = i;while(num > 0){ans[i]++;num = num & (num-1);}}return ans;}
}

3.颠倒二进制位

思路:不断将 n 的最低位复制到结果的对应位置,实现了二进制位的翻转。值得注意的是,这里处理的是无符号整数,因此不需要考虑符号位,Java使用逻辑移位符号>>>

public int reverseBits(int n) {int res = 0; // 用于存储翻转后的结果int pos = 31; // 由于 int 是32位,所以从最高位开始处理,即第31位while (pos >= 0) { // 从最高位向最低位循环处理res += (n & 1) << pos; // (n & 1) 取得 n 的最低位,并将其左移 pos 位pos--; // 处理下一位n = n >>> 1; // 右移 n,去掉已经处理过的最低位}return res; // 返回翻转后的结果
}

 二、位实现加减乘除专题

1.两数之和

思路:进位求和+不进位求和

  1. 进入 while 循环,只要 b 不等于0,就继续执行。这个循环会一直执行,直到没有进位产生,也就是 b 变成0。

  2. 在循环中,首先计算进位 carry。进位是通过将 ab 进行按位与操作 a & b,然后将结果左移一位 << 1 得到的。这一步模拟了进位的计算。

  3. 接下来,通过异或操作 a ^ b 求得不包括进位的和。异或操作可以将两个数相加,但不考虑进位。

  4. 将进位 carry 的值赋给 b,以便将进位传递到下一轮循环。

  5. 继续循环,直到没有进位产生,也就是 b 变成0。

  6. 最后,返回 a,即最终的和。

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

以123+623为例:

1. 初始状态:a = 123(二进制 1111011),b = 623(二进制 1001110111)。

2. 进入循环,b 不等于 0:

   - 计算进位 `carry`:(a & b) << 1 = (1111011 & 1001110111) << 1 = (1001011) << 1 = 10010110。

   - 计算不包括进位的和 `a`:a = a ^ b = 1111011 ^ 1001110111 = 1001010100。

   - 将进位传递给 `b`:b = carry = 10010110。

3. 进入下一轮循环,b 不等于 0:

   - 计算进位 `carry`:(a & b) << 1 = (1001010100 & 10010110) << 1 = 10000000 << 1 = 100000000。

   - 计算不包括进位的和 `a`:a = a ^ b = 1001010100 ^ 10010110 = 1001110010。

   - 将进位传递给 `b`:b = carry = 100000000。

4. 进入下一轮循环,b 不等于 0:

   - 计算进位 `carry`:(a & b) << 1 = (1001110010 & 100000000) << 1 = 100000000 << 1 = 1000000000。

   - 计算不包括进位的和 `a`:a = a ^ b = 1001110010 ^ 100000000 = 1001110010。

   - 将进位传递给 `b`:b = carry = 1000000000。

5. 进入下一轮循环,b 不等于 0:

   - 计算进位 `carry`:(a & b) << 1 = (1001110010 & 1000000000) << 1 = 1000000000 << 1 = 10000000000。

   - 计算不包括进位的和 `a`:a = a ^ b = 1001110010 ^ 1000000000 = 1001110010。

   - 将进位传递给 `b`:b = carry = 10000000000。

6. 进入下一轮循环,b 不等于 0:

   - 计算进位 `carry`:(a & b) << 1 = (1001110010 & 10000000000) << 1 = 0 << 1 = 0。

   - 计算不包括进位的和 `a`:a = a ^ b = 1001110010 ^ 0 = 1001110010。

   - 将进位传递给 `b`:b = carry = 0。

7. 进入下一轮循环,b 等于 0,循环结束。

8. 返回最终结果 `a`,即 1001110010 对应的十进制数,结果是 746。

所以,123 + 623 的结果是 746,这个算法成功地完成了加法操作。

2.递归乘法

普通解法,将乘法转换成多次加法

class Solution {public int multiply(int A, int B) {int res = 0;if(A>B){int t = A;A = B;B =t;}while(A-->0){res += B;}return res;}
}

思路:【优化】将两个数相乘的过程转化为一系列的加法和移位操作,从而减少了乘法运算的次数

n = a0*2^0 + a1*2^1 + a2*2^2 + a3*2^3........+ak*2^k

拆分成2的幂的和的方法是将乘法操作分解成了多次左移和加法操作,这是一种基于二进制的思考方式,也是快速乘法的一部分。

举例说明:13 * 12 = 13 * (8 + 4) = 13 * 8 + 13 * 4 = (13 << 3) + (13 << 2)

这个示例中,我们首先将12分解为8和4,然后用13分别乘以8和4。在二进制视角下,8可以表示为2的三次方(8 = 2^3),4可以表示为2的二次方(4 = 2^2)。因此,我们可以将这个乘法操作分解为两个左移和相加的操作。

  1. 首先,将13左移3位,得到13 * 8 = (13 << 3)。
  2. 接下来,将13左移2位,得到13 * 4 = (13 << 2)。
  3. 最后,将这两个部分相加,即(13 << 3) + (13 << 2),就得到了13 * 12的结果。

这种方法充分利用了二进制的特性,通过左移和相加的方式来实现乘法操作,从而提高了计算效率。

  1. 首先,将13和12转换为二进制数。13的二进制表示是1101,12的二进制表示是1100。

  2. 初始化结果为0。

  3. 从右往左,第一个数为0,进行2次幂,13*2。

  4. 第二个数的最右位是0,进行2次幂,13*2*2。

  5. 第二个数的下一位是1,乘数的二进制现在为0011,这时我们将结果加上,(最低位碰到1说明一次拆分完成要相加了)结果变为13*2*2(进行了4次加法)。

  6. 乘数对半减小0001,被乘数进行2次幂,13*2*2*2

  7. 接下来是第三位,同样是1,这时将结果再次加上13*2*2*2(8次加法),结果变为13*2*2(4次)+13*2*2*2(8次)。

  8. 最后一位是0,不进行任何操作。

  9. 现在,我们已经完成了所有位的计算,结果是13*12。

例如:14*127(11111111)/ (1+2+4+8+16+32+64)

14*127 = 14*1+14*2+14*4+14*8+14*16+14*32+14*64

14*125(11111101)= 14*1+14*4+14*8+14*16+14*32+14*64

class Solution {public int multiply(int A, int B) {int min = Math.min(A,B);int max = Math.max(A,B);int ans = 0;while(min!=0){//奇数相加if((min&1) == 1){ans += max;}min = min >> 1; //对半减小乘数max += max; //进行2的幂次}return ans;}
}

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

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

企业架构LNMP学习笔记15

客户端缓存&#xff1a; B/S架构里&#xff0c;Browser是浏览器&#xff0c;就是客户端。 客户端缓存告知浏览器获取服务段的信息是在某个区间时间段是有效的。 每次请求从服务器拿一遍数据&#xff0c;数据没有变化&#xff0c;影响带宽&#xff0c;影响时间。刷新又要去加载…

Vue3中快速简单使用CKEditor 5富文本编辑器

Vue3简单使用CKEditor 5 前言准备定制基础配置富文本配置目录当前文章demo目录结构 快速使用demo 前言 CKEditor 5就是内嵌在网页中的一个富文本编辑器工具 CKEditor 5开发文档&#xff08;英文&#xff09;&#xff1a;https://ckeditor.com/docs/ckeditor5/latest/index.htm…

cartographer 学习

cartographer 学习 编译并运行代码 由于cartographer整体分成了两个包 一个是cartographer,不带ros的内容另一个是cartographer_ros&#xff0c;是已ros项目构建的 这样因为带了普通cmake的包&#xff0c;就没法使用catkin_make了&#xff0c;只能使用catkin_make_isolated …

Scala面向对象编程(高级部分)

1. 静态属性和静态方法 &#xff08;1&#xff09;回顾Java中的静态概念 public static 返回值类型 方法名(参数列表) {方法体} 静态属性… 说明: Java中静态方法并不是通过对象调用的&#xff0c;而是通过类对象调用的&#xff0c;所以静态操作并不是面向对象的。 &#xff0…

谈谈对OceanBase单机分布式一体化的思考

关于作者&#xff1a; 杨传辉&#xff0c;OceanBase CTO。2010 年作为创始成员之一加入 OceanBase 团队&#xff0c;主导了 OceanBase 历次架构设计和技术研发&#xff0c;从无到有实现 OceanBase 在蚂蚁集团全面落地。同时&#xff0c;他也主导了两次 OceanBase TPC-C 测试并打…

管理类联考——数学——汇总篇——知识点突破——数据分析——计数原理——排列组合——成双

&#x1f30a; 配对问题的解题思路&#xff1a;配对问题主要以鞋子或者手套来作为命题对象&#xff0c;其核心在于成双不成双&#xff0c;对于成双问题&#xff0c;直接选取整双即可&#xff0c;对于不成双问题&#xff0c;要先取成双的&#xff0c;然后从每双中取单只即可。 …

go语言学习笔记

Go学习 一直想学一门新语言&#xff0c;难度又不想太大&#xff0c;C和Java都会但是不怎么精通&#xff0c;某天看到Go语言&#xff0c;好的&#xff0c;就是它了。总体来说&#xff0c;go语言的学习还是相对简单&#xff0c;有编程基础的入手很快。 简介 go是一种并发、带垃…

【设计模式】一、设计模式七大原则

文章目录 设计模式概述设计模式七大原则设计模式的目的设计模式七大原则1. 单一职责原则2. 接口隔离原则3. 依赖倒转(倒置)原则4. 里氏替换原则5. 开闭原则&#xff08;Open-Closed Principle简称OCP原则&#xff09;6. 迪米特法则7. 合成复用原则&#xff08;Composite Reuse …

ABB REF615C-D HCFFAEAGABC2BAA1XD控制继电器

多功能保护&#xff1a;REF615C-D 继电器具备多种保护功能&#xff0c;包括过流、短路、地故障、欠频、过频、欠电压、过电压等&#xff0c;可用于监测和保护电力系统中的设备。 通信能力&#xff1a;该继电器支持通信协议&#xff0c;如IEC 61850、Modbus等&#xff0c;使其能…

YOLOv5算法改进(11)— 替换主干网络之EfficientNetv2

前言&#xff1a;Hello大家好&#xff0c;我是小哥谈。EfficientNetV2是一个网络模型&#xff0c;旨在提供更小的模型和更快的训练速度。它是EfficientNetV1的改进版本。EfficientNetV2通过使用更小的模型参数和采用一种称为Progressive Learning的渐进学习策略来实现这一目标。…

Benchmarking Chinese Text Recognition: Datasets, Baselines| OCR 中文数据集【论文翻译】

基础信息如下 https://arxiv.org/pdf/2112.15093.pdfhttps://github.com/FudanVI/benchmarking-chinese-text-recognition Abstract 深度学习蓬勃发展的局面见证了近年来文本识别领域的迅速发展。然而&#xff0c;现有的文本识别方法主要针对英文文本。作为另一种广泛使用的语…

NIFI实现JSON转SQL并插入到数据库表中

说明 本文中的NIFI是使用docker进行安装的&#xff0c;所有的配置参考&#xff1a;docker安装Apache NIFI 需求背景 现在有一个文件&#xff0c;里面存储的是一些json格式的数据&#xff0c;要求将文件中的数据存入数据库表中&#xff0c;以下是一些模拟的数据和对应的数据库…

初试小程序轮播组件

文章目录 一、轮播组件&#xff08;一&#xff09;swiper组件1、功能描述2、属性说明 &#xff08;二&#xff09;swiper-item组件1、功能描述2、属性说明 二、案例演示&#xff08;一&#xff09;运行效果&#xff08;二&#xff09;实现步骤1、创建小程序项目2、准备图片素材…

工程管理系统简介 工程管理系统源码 java工程管理系统 工程管理系统功能设计

鸿鹄工程项目管理系统 Spring CloudSpring BootMybatisVueElementUI前后端分离构建工程项目管理系统 1. 项目背景 一、随着公司的快速发展&#xff0c;企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性&#xff0c;公司对内部工程管…

微信小程序 房贷计算器 js代码终极版

这里写目录标题 展示图1.在utils 中创建文件calculateMortgage.ts2. 在需要使用的地方引入并传参 展示图 1.在utils 中创建文件calculateMortgage.ts /** 假设房贷本金是60万&#xff0c;贷款年利率为4.8%即月利率为0.4%&#xff0c;分20年即240期偿还&#xff0c;等额本金还款…

AWS-数据库迁移工具DMS-场景:单账号跨区域迁移RDS for Mysql

参考文档&#xff1a; 分为几个环节&#xff1a; 要使用 AWS DMS 迁移至 Amazon RDS 数据库实例&#xff1a; 1.创建复制实例 有坑内存必须8g或者以上&#xff0c;我测试空库 都提示内存不足 2.创建目标和源终端节点 目标空库也得自己创建哈 3.刷新源终端节点架构 4.创建迁…

echarts环图配置

echarts环图配置 1、安装echarts npm install echarts4.9.02、页面引入echarts import echarts from echarts;3、应用 template片段 <div class"chart-wrap"><div id "treeChart" style "width: 180px; height:180px;" ><…

vite介绍

vite vite是一种新的前端构建工具&#xff0c;vite借助了浏览器对ESM的支持&#xff0c;采用和传统webpack打包完全不一致的unbundle打包机制&#xff1b; vite的快主要体现在两个方面&#xff0c;快速的冷启动和快速的热更新 快速的冷启动&#xff1a;vite只需启动一台静态页…

LeetCode刷题笔记【24】:贪心算法专题-2(买卖股票的最佳时机II、跳跃游戏、跳跃游戏II)

文章目录 前置知识122.买卖股票的最佳时机II题目描述贪心-直观写法贪心-优化代码更简洁 55. 跳跃游戏题目描述贪心-借助ability数组贪心-只用int far记录最远距离 45.跳跃游戏II题目描述回溯算法贪心算法 总结 前置知识 参考前文 参考文章&#xff1a; LeetCode刷题笔记【23】…

SpringBoot隐藏文件

1.设置 2.输入file Types 3.点击忽略文件或者文件夹 4.成功