首页 > 其他分享 >异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?

时间:2022-11-03 12:34:46浏览次数:71  
标签:arr XOR 运算 巧用 异或 奶牛 变量 数字

开心一刻

  两头奶牛在一起吃草,其中一头(奶牛甲)越吃越慢,一副若有所思的模样,另一头奶牛(奶牛乙)发觉了,开始了对话

  奶牛乙:搁那合计啥呢?

  奶牛甲:你帮我合计合计

  奶牛乙:咋地了

  奶牛甲:我吃的是草,挤出来的是奶,也就是说我把没用的变成有用的了

  奶牛乙:是这个事

  奶牛甲:人呢,喝的是奶,拉出来的是粑粑

  奶牛乙:咋地了

  奶牛甲:他又把有用的变成没用的了,我这不白干了吗

  奶牛乙:你说的不对

  奶牛甲:不对吗?

  奶牛乙:那粑粑做成化肥,有化肥才能长草,所以说你吃的不是草,是粑粑

  奶牛甲:啊 ???

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_空间复杂度

概念

  关于“位”运算,大家或多或少都知道点,比如与运算(&)、或运算(|)、异或运算(^)、取反运算(~)、左移(<<)、右移(>>)

  因为今天的主角是:异或运算,其他的位运算就不在本文展开了,大家自行去查阅

exclusive OR ,简称 XOR

  关于或运算,我们都比较清楚,只有当两个位都是0时,结果才为0,其他情况结果都是1,也就是说或运算结果为 1 的情况两种

  (1)一个位是 1,另一个位是 0

  (2)两个位都是 1

  有时候我们需要明确区分这两种情况,怎么办?

XOR ,它排除了情况(2),只有情况(1),也就说:一个位是 1,另一个位是 0 时, XOR 的结果才是 1,也可称做无进位相加

XOR 可以看成是更单纯的 OR 运算,正好对应了它的英文名: exclusive OR ,用来判断两个值是否不同(不同、不同、不同!!!)

XOR

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_时间复杂度_02

运算定律

  我们学过的加法、乘法都有运算定律,异或运算也有它的运算定律

  N ^ N = 0

  N 表示任何值,也就是说:两个相等的值做异或运算,得到的结果是 0

XOR

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_变量交换_03

  我们来看个具体的例子:15 ^ 15

01111

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_变量交换_04

  N ^ 0 = N

  一个值与 0 做异或运算,得到的结果仍是这个值

  例如:15 ^ 0 = 15

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_变量交换_05

  N ^ M = M ^ N

  同加法有交换律、乘法也有交换律一样,异或运算也有交换律

  例如:15 ^ 8 = 8 ^ 15

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_变量交换_06

  (N ^ M) ^ Y = N ^ (M ^ Y)

  同加法有结合律、乘法有结合律一样,异或运算也结合律

  例如:(15 ^ 8) ^ 3 = 15 ^ (8 ^ 3)

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_空间复杂度_07

具体应用

  前面讲了那么多理论,大家可能没啥感觉,接下来我们就看看具体的案例,让大家好好感觉感觉

  不用额外的变量,交换两个变量的值

  楼主在以往的面试过程中,确确实实被面到过这个问题,关键是当时没答上来

XOR

XOR

  N = N ^ M  // N = 5 ^ 6, M = 6

  M = N ^ M  // M = 5 ^ 6 ^ 6 = 5 ^ 0 = 5,N = 5 ^ 6

  N = N ^ M  // N = 5 ^ 6 ^ 5 = 6 ^ 0 = 6,M = 5

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_异或运算_08

  找出一串数字中唯一出现了奇数次的数字

  问题详细描述:已知一串数中,只有 1 个数字出现了奇数次,其他数字都出现了偶数次,如何快速找到这个奇数次的数字

哈希表

哈希表 ,没有存在则存入 哈希表 ,存在了则从 哈希表

哈希表

哈希表 方案的时间复杂度是 O(N) ,额外空间复杂度也是 O(N)

O(1)

XOR 出马了,我们结合 N ^ N = 0

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_时间复杂度_09

 

O(1) ,只用到了两个额外变量: eor 、 cur

  找出 1 至 n 中缺少的那个数

  问题详细描述:一串数字包含 n-1 个成员,这些数字是 1 到 n 之间的整数,且没有重复,请找出缺少的那个数字

  常规解法:从 1 累和到 n,然后再逐个减去这串数字

1 + 2 + ... + n - arr[0] - arr[1] - ... - arr[n-2]

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_时间复杂度_10

O(N) ,空间复杂度 O(1)

XOR

  我们将这串数组与 1 至 n 的每个整数放在一起进行全部的异或运算

arr[0] ^ arr[1] ^ ... ^ arr[n-2] ^ 1 ^ 2 ^ ... ^ n

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_变量交换_11

  那么得到的结果就是缺少的那个数

  不存在溢出的风险,并且位运算比加、减运算更快

  找出 1 至 n 中重复的那个数字

  问题详细描述:一串数字包含 n+1 个成员,这些数字是 1 到 n 之间的整数,只有一个数字出现了两次,其他数字都只出现一次,请找出重复出现的那个数字

  与问题:​​找出 1 至 n 中缺少的那个数​​解法一致

arr[0] ^ arr[1] ^ ... ^ arr[n] ^ 1 ^ 2 ^ ... ^ n

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_时间复杂度_12

  找出一串数字中出现了奇数次的那两个数字

  问题详细描述:已知一串数中,有 2 个数字出现了奇数次,其他数字都出现了偶数次,如何快速找到那 2 个奇数次的数字

O(N) ,空间复杂度 O(1)

奇数次 、 偶数次 字眼已经产生了条件反射:用 XOR

XOR ,那么得到的结果 eor = a ^ b

a != b ,则 eor != 0 ,所以 eor

eor 二进制最右边的 1: int

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_变量交换_13

rightOne 可以将数字串拆成两部分:cur & rightOne = 0 和 cur & rightOne != 0

  a、b 分别落在两侧,其他偶数个的数字只会落在某一侧,整个数字串就被拆分成两个​​找出一串数字中唯一出现了奇数次的数字​​的数据模型了

  分别从两侧中找出奇数次的数字即可

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_异或运算_14

  完整代码如下

异或运算的巧用 → 不用额外的变量,如何交换两个变量的值?_时间复杂度_15

  这个解法没那么好理解,大家好好琢磨琢磨

总结

XOR

奇数个 、 偶数个 、 缺失的 、 重复的 字眼,可以往 XOR

  3、关于 不用额外的变量交换两个变量的值,大家了解就好,不推荐使用

    阅读性差,另外相比临时变量,它可能会出问题

  4、示例代码地址

    ​​ExclusiveORTest​

参考

  ​​That XOR Trick​



标签:arr,XOR,运算,巧用,异或,奶牛,变量,数字
From: https://blog.51cto.com/u_13423706/5819391

相关文章

  • java开发环境搭建及环境变量配置
    一、 JDK的下载与安装jdk下载地址:https://www.oracle.com/java/technologies/downloads/#java8根据电脑系统及位数选择下载对应jdk安装包以下用windows系统为例,jdk安......
  • Java中“成员变量,局部变量,静态变量”三者区别说明
    转自:http://java265.com/JavaCourse/202111/1728.html下文笔者讲述java中成员变量,局部变量,静态变量的不同之处,如下所示: 成员变量局部变量静态变量定义位置......
  • C++ 引用为变量起别名
    引用的基本使用 intmain(){//给变量起别名//语法数据类型&别名=变量名inta=10;int&b=a;cout<<"a......
  • 无需插件,巧用Chrome浏览器实现对整个网页的高清截屏
    文/王不留(微信公众号:王不留) 我们有时需要截取网页的全图。发现一个简单方法。记录之。 这个方法需要使用Chrome浏览器。 1、输入网址: ​​https://www.google.cn/chro......
  • Java 中的 Lambda 表达式不能访问局部变量?
    问题现象从Java8开始新增的Lambda表达式,可以使代码变的更加简洁紧凑,使用中还会碰到一个问题:Variableusedinlambdaexpressionshouldbefinaloreffectivelyf......
  • jmeter变量函数以及抓包用法
    抓包代理服务器:自己启动一个代理服务器本地,要使用代理服务器的ip和端口,使用自己启动的代理服务器操作步骤添加线程组测试计划>非测试元件>http代理服务器一定......
  • 巧用shell脚本批量替换字符串
    ​作者:田逸(formyz)需求描述​有一个网站,因为域名变更,除了需要重新做域名解析外,还需要对网站目录的包含原域名的文件进行替换。包含域名(主机名)关键字的文件相当的多,它们分布在......
  • C++——变量作用域
    全局变量在全部函数(包括main函数)外面定义的是全局变量;在整个程序生命周期内都是有效的,在定义位置之后的任意函数中都能访问(在定义位置之前的任何函数都不能访问)全局变量......
  • 1-2 变量与递归函数
    变量作用域(全局变量和局部变量)变量变量起作用的范围称为变量的作用域,不同作用域内同名变量之间互不影响。变量分为:全局变量、局部变量。全局变量1.在函数和类定义之外......
  • shell语法2-默认变量、数组
    一:文件参数变量1、在执行shell脚本时,可以向脚本传递参数。$1是第一个参数,$2是第二个参数,以此类推。特殊的,$0是文件名(包含路径)#!/bin/bashecho"文件名:"$0echo"第一个参......