leecode 1486. 数组异或操作

题目描述
给你两个整数,n 和 start 。数组 nums 定义为:nums[i] = start + 2*i(下标从 0 开始)且 n == nums.length 。
请返回 nums 中所有元素按位异或(XOR)后得到的结果。

示例 1:
输入:n = 5, start = 0
输出:8
解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。 “^” 为按位异或 XOR 运算符。
示例 2:
输入:n = 4, start = 3
输出:8
解释:数组 nums 为 [3, 5, 7, 9],其中 (3 ^ 5 ^ 7 ^ 9) = 8.

链接:https://leetcode-cn.com/problems/xor-operation-in-an-array

最简单的做法:直接模拟即可

这么简单就完事儿了,确实,但是并没有得到本题目的精髓

异或的性质: 4i ^ (4i+1) ^ (4i+2) ^ (4i+3) = 0

要计算的是:start ^ (start + 2i)^ (start + 4i ) ^ ……^(start+2(n-1))
这些数的奇偶性质相同,因此它们的二进制表示中的最低位或者均为 1,或者均为 0。于是我们可以把参与运算的数的二进制位的最低位提取出来单独处理。当且仅当 start 为奇数,且 n 也为奇数时,结果的二进制位的最低位才为 1。

具体可以参考官网题解:题解 需要注意的几点为:

  • (s⊕(s+1)⊕(s+2)⊕⋯⊕(s+n−1))×2+e,其中s=start/2。e表示运算结果的最低位。即我们单独处理最低位,而舍去最低位后的数列恰成为一串连续的整数。 为什么要单独把 e 拎出来?题目中说是为了形成一串连续的整数。参与异或运算的要不是偶数要不是奇数,为了转化成连续的整数需要为每个数除以2得到连续的数列,但是除以2是进行的是下取整,有些数字比如奇数除以2除不尽,舍掉的那部分怎么办?从余数中来获得。

  • (sumXor(s−1)⊕sumXor(s+n−1))*2+e。其中 乘以2 表示 左移一位,为什么前面要sumXor(s−1)?是因为计算的时候 是从 s 开始的,而sumXor(x) 表示从 0 到 x 的异或结果,因此需要使用异或运算的 x^x =0 0 ^ x =x 这两条性质,将前面无用的部分消掉。

  • 代码最后是 return ret << 1 | e; 为什么要取 | 运算,因为求解出来的e 表示最终结果末尾位置为1,需要把这一 1 合并到最终结果中,与运算就不适合这样的,两个1相 与 才为1,这一末尾位置的结果就不对了。

  • 这样计算复杂度为O(1) ,即使给定的 n 很大,也能很快求解

class Solution {
public:
    int sumXor(int x) {
        if (x % 4 == 0) {
            return x;
        }
        if (x % 4 == 1) {
            return 1;
        }
        if (x % 4 == 2) {
            return x + 1;
        }
        return 0;
    }

    int xorOperation(int n, int start) {
        int s = start >> 1, e = n & start & 1;
        int ret = sumXor(s - 1) ^ sumXor(s + n - 1);
        return ret << 1 | e;
    }
};

链接:https://leetcode-cn.com/problems/xor-operation-in-an-array/solution/shu-zu-yi-huo-cao-zuo-by-leetcode-solution/

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值