前缀异或算法以及异或的其它基础应用


1.异或的概念(对于新手)


异或是一种逻辑运算符,对两个数异或的结果实际是看其在二进制下比特位是否相同:

异或运算符 ^ (⊕)
核心:二进制下对应位值相同为0,不同为1

/*
假设我们要对9和7进行异或,其中9的二进制为1001,7为0111
7 -- 0 1 1 1
⊕
9 -- 1 0 0 1
-----------
14-- 1 1 1 0
因此7^9 = 14
*/

/*
异或的一些基本运算规则:
a ^ a = 0,
0 ^ a = a,
a ^ b = b ^ a,
a ^ (b ^ c) = (a ^ b) ^ c
*/


2.前缀异或数组


在做异或题目时,经常需要计算区间内的异或值,为了避免使用暴力方法运算,就要用到前缀异或数组的方法:

假设我们有数组arr{1,2,3,4,7,9}

前0项的异或值为:0 = 0
前1项的异或值为:0 ^ 1 = 1
前2项的异或值为:1 ^ 2 = 3
前3项的异或值为:1 ^ 2 ^ 3 = 0
前4项的异或值为:1 ^ 2 ^ 3 ^ 4 = 4
前5项的异或值为:1 ^ 2 ^ 3 ^ 4 ^ 7 = 3
前6项的异或值为:1 ^ 2 ^ 3 ^ 4 ^ 7 ^ 9 = 10

因此他们的前缀异或数组为pre{0,1,3,0,4,3,10}

假设我们要计算arr数组第3到第六项的异或值,此时我们不需要暴力的去计算:
“3 ^ 4 ^ 7 ^ 9”

因为我们知道(3 ^ 4 ^ 7 ^ 9) = (1 ^ 2) ^ (1 ^ 2 ^ 3 ^ 4 ^ 7 ^ 9)

很明显:1 ^ 2是前2项的值;1 ^ 2 ^ 3 ^ 4 ^ 7 ^ 9是前6项的值
因此第3到第6项的值为:3 ^ 10 = 9

当求第m到第n项的异或值:pre[m-1] ^ pre[n]




举个栗子(LeetCode 1442):

题目:现需要从数组中取三个下标 i、j 和 k ,其中 (0 <= i < j <= k < arr.length) 。

a 和 b 定义如下:

a = arr[i] ^ arr[i + 1] ^ … ^ arr[j - 1]
b = arr[j] ^ arr[j + 1] ^ … ^ arr[k]

请返回能够令 a == b 成立的三元组 (i, j , k) 的数目。

class Solution {
   
    public int countTriplets(</
  • 15
    点赞
  • 22
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 7
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 7
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凤梨c

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值