当前位置: 首页 > news >正文

数据结构与算法2-俩变量值交换、理解异或位运算

文章目录

  • 1. 变量值交换方法1
  • 2. 变量值交换方法2
  • 3. 理解异或位运算,相当于无进位相加
  • 4. 数组中只有一种数出现了奇数次,找出这种数
  • 5. 数组中只有两种数出现了奇数次,找出这两种数
  • 6. 把不等于0的数最右侧的的1提取出来,其余数置为0,得到值形如:0000100

1. 变量值交换方法1

    public static void swap(int[] arr, int i, int j) {int tmp = arr[i];arr[i] = arr[j];arr[j] = tmp;}

2. 变量值交换方法2

    public static void swap(int[] arr, int i, int j) {// 这里的i 和 j 不能相等,否则就用到了同一内存,就会变为0;// arr[i] 和 arr[j]的值可以相等,它们的值是存在不同栈中,并不是同一块内存if (i == j) {return;}arr[i] = arr[i] ^ arr[j];arr[j] = arr[i] ^ arr[j];arr[i] = arr[i] ^ arr[j];}

步骤分析:

int a = 甲;
int b = 乙;
a = a ^ b; // a = 甲 ^ 乙;
b = a ^ b; // b = 甲 ^ 乙 ^ 乙 = 甲 ^ (乙 ^ 乙) = 甲 ^ 0 = 甲
a = a ^ b; // a = 甲 ^ 乙 ^ 甲 = 甲 ^ 甲 ^ 乙 = 0 ^ 乙 = 乙

3. 理解异或位运算,相当于无进位相加

异或位运算原理:相同为0, 不同为1

  • 0 1 -> 1
  • 1 0 -> 1
  • 0 0 -> 0
  • 1 1 -> 0

满足的性质:

  • 0 ^ N = N
  • N ^ N = 0;
  • 满足交换律:a ^ b = b ^ a;
  • 满足结合率:a ^ b ^ c = a ^ (b ^ c);

4. 数组中只有一种数出现了奇数次,找出这种数

	public static void main(String[] args) {int[] arr = {2, 2, 3, 3, 7};printOddTimesNum1(arr);}/** 数组中只有一种数出现了奇数次,找出这种数** */public static void printOddTimesNum1(int[] arr) {int eor = 0;for (int cur : arr) {eor ^= cur;}System.out.println(eor);}

打印结果:

7

5. 数组中只有两种数出现了奇数次,找出这两种数

	public static void main(String[] args) {int[] arr2 = {2, 2, 3, 3, 7, 8};printOddTimesNum2(arr2);}/** 数组中只有两种数出现了奇数次,找出这两种数** */public static void printOddTimesNum2(int[] arr) {int eor = 0, onlyOne = 0;for (int curNum : arr) {eor ^= curNum;}// 由于只有a、b是奇数次:eor = a ^ b;// 由于是两种数,所以它们不相等:eor != 0;// 由于不等于0:eor必然有一个位置上是1int rightOne = eor & (~eor + 1); // 把不等于0的数最右侧的的1提取出来,其余数置为0,得到值形如:0000100for (int cur : arr) {// 等于1亦可,两个奇数次的数在rightone等于1这个这个位置异或为1,代表它们在这个位置一个为0,一个为1// 偶数次的数也会被分为两个阵营,不过下面onlyOne与其中一个阵营异或,由于不管哪个阵营都是偶数次,阵营内部异或结果都是0
//            if ((cur & rightOne) == 1) { if ((cur & rightOne) == 0) {// 将onlyOne,初始为0,与两个奇数次的数中的一个,设为a,和偶数次数的一个阵营异或得到的就是a,// 因为其他的数都是偶数次,一起异或得到0,那么只剩下所有的a异或,由于是奇数次,所以结果是aonlyOne ^= cur;}}// 所以onlyOne就是a,eor = a ^ b; b = eor ^ a;System.out.println(onlyOne + "\n" + (eor ^ onlyOne));}

打印结果:

8
7

6. 把不等于0的数最右侧的的1提取出来,其余数置为0,得到值形如:0000100

int rightOne = eor & (~eor + 1);

相关文章:

  • 还敢自学黑客,骂醒一个算一个(网络安全/信息安全)
  • 【Android】【Bluetooth Stack】蓝牙音乐协议分析之音频控制与信息加载(超详细)
  • 二叉树的遍历及线索二叉树试题(三)
  • 【CMake】所见所闻所学
  • 【蓝桥杯-单片机】基于定时器的倒计时程序设计
  • 基础:TCP四次挥手做了什么,为什么要挥手?
  • 编程题:相同数字的积木游戏(Java)
  • 暴力快速入门强化学习
  • 2024年阿里云服务器地域和可用区所在地区城市分布表
  • MT2191 整数大小比较(高精度)
  • React—— props校验(非typescript校验类型)
  • 目标检测——PP-YOLO算法解读
  • 33-Java服务定位器模式 (Service Locator Pattern)
  • js中的new Map的用法
  • [ESP32] 编码旋钮驱动
  • 时间复杂度分析经典问题——最大子序列和
  • 【跃迁之路】【669天】程序员高效学习方法论探索系列(实验阶段426-2018.12.13)...
  • classpath对获取配置文件的影响
  • CoolViewPager:即刻刷新,自定义边缘效果颜色,双向自动循环,内置垂直切换效果,想要的都在这里...
  • Github访问慢解决办法
  • learning koa2.x
  • Linux快速配置 VIM 实现语法高亮 补全 缩进等功能
  • Lsb图片隐写
  • MobX
  • python3 使用 asyncio 代替线程
  • Quartz实现数据同步 | 从0开始构建SpringCloud微服务(3)
  • SegmentFault 技术周刊 Vol.27 - Git 学习宝典:程序员走江湖必备
  • SegmentFault 社区上线小程序开发频道,助力小程序开发者生态
  • 记录:CentOS7.2配置LNMP环境记录
  • 技术:超级实用的电脑小技巧
  • 前端相关框架总和
  • 人脸识别最新开发经验demo
  • 微信公众号开发小记——5.python微信红包
  • 找一份好的前端工作,起点很重要
  • 《天龙八部3D》Unity技术方案揭秘
  • puppet连载22:define用法
  • Spring第一个helloWorld
  • 大数据全解:定义、价值及挑战
  • 机器人开始自主学习,是人类福祉,还是定时炸弹? ...
  • ​无人机石油管道巡检方案新亮点:灵活准确又高效
  • # Java NIO(一)FileChannel
  • #pragma预处理命令
  • #QT(智能家居界面-界面切换)
  • #我与Java虚拟机的故事#连载01:人在JVM,身不由己
  • (笔记)Kotlin——Android封装ViewBinding之二 优化
  • (力扣记录)1448. 统计二叉树中好节点的数目
  • (六)DockerCompose安装与配置
  • (深度全面解析)ChatGPT的重大更新给创业者带来了哪些红利机会
  • (转)EXC_BREAKPOINT僵尸错误
  • (转)树状数组
  • .Family_物联网
  • .NET Core6.0 MVC+layui+SqlSugar 简单增删改查
  • .Net Redis的秒杀Dome和异步执行
  • .net 程序 换成 java,NET程序员如何转行为J2EE之java基础上(9)
  • .NET 中创建支持集合初始化器的类型