leetcode每日一题——1486. 数组异或操作

今天看到的第一眼,诶,竟然是个simple的,那应该会很简单的,然后一看题

我就傻眼了,异或操作……,两三年前上离散数学的时候学过,很久不用,早就已经忘了。那么先查一下,这个异或运算到底是怎么算的吧。

  1. 关于异或运算
    1. 异或运算最能讲明白的一句话就是“同为0,异为1”,即如果两个位次的数相等,那么这一位的结果就是0,如果这两个位次的数不等,那么这一位的结果就是1。
    2. 在C++编程语言里,它的运算符是“^”,那么异或运算的公式可以写成:a ^ b=(~a & b) | (a & ~b)
    3. 我们以“2^4”为例:
      1. “2”转化为2进制是“010”,“4”的二进制是“100”。
      2. 那么对于每一位进行异或运算,相同的是0,不同的为1
      3. 那么,最后的结果就是“110”,转化为十进制就是6
      4. 即 2^4=6
    4. 性质:
      1. x^x=0;

      2. 交换率:x^y=y^x

      3. 结合率:(x^y)^z = x^(y^z)

      4. 自反性:x^y^y=x,  x^x^y=y

      5. 对于i>=0,有 4i ^ (4i+1) ^ (4i+2) ^ (4i+3)=0

  2. 解题

    1. 比较直观的方法就是一个循环,在循环过程中对所有元素挨个进行异或运算,最后得到结果。时间复杂度是O(n),空间复杂度是O(1)。代码(C++)如下

      class Solution {
      public:
          int xorOperation(int n, int start) {
              int res = start;
              for(int i=1;i<n;i++)
              {
                  res = res^(start+2*i);
              }
              return res;
          }
      };

       

  3. 第二种方法则应用到了异或运算的性质5.
    1. 那么,对于数组nums中的所有元素,nums[i]=start+2*i,这些元素要么都是偶数,要么都是奇数,这是由start的初始值决定的。所以这些数转成二进制之后,最后一位的数值都相同,奇数就都是1,偶数则都是0。因为他们都相同,所以异或结果的最后一位必然是0。
    2. 将nums中的所有元素都下除以2(比如5/2=2),得到的值就是一个从start/2开始长度为n的连续数组。(比如对于实例二来说,得到的结果是 [1,2,3,4])
    3. 那么对于新的数组中元素来说,它们每个4*i到4*i+3的元素异或,得到的结果就是0,0异或任何一个数仍等于那个数,所以消去它们。故,对于有n个数组的元素来说,只需要计算前面m1个值异或后m2个值的结果(m1\m2均小于等于3)。
    4. 第3步得到的结果的二进制在后面再加个0,或者结果的十进制乘以2,得到的就是最终的结果。

(当然,在第3步计算的时候,直接用原始数据来计算,等价于先除2再乘2的结果,所以化简以后只是计算前面m1个值异或后m2个值的结果即可)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值