Leetcode 1486. XOR Operation in an Array(数组异或操作) (题目 + 详解 + C++代码)

题目描述:

Given an integer n and an integer start.
Define an array nums where nums[i] = start + 2*i (0-indexed) and n == nums.length.
Return the bitwise XOR of all elements of nums.

Input: n = 5, start = 0
Output: 8
Explanation: Array nums is equal to[0, 2, 4, 6, 8] where (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8

Input: n = 4, start = 3
Output: 8
Explanation: Array nums is equal to [3, 5, 7, 9] where (3 ^ 5 ^ 7 ^ 9) = 8.

Input: n = 1, start = 7
Output: 7

Input: n = 10, start = 5
Output: 2

Constraints:
1 <= n <= 1000
0 <= start <= 1000
n == nums.length

前置知识

有如下定理成立(想想二进制表示,就知道为什么是0了):
在这里插入图片描述

令 f(n) = 1 ^ 2 ^ 3 ^ 4 ^ 5 ^ …n,求所有的f(n)

  • n % 4 == 0 时,n = 4时,f(4) = 4; n = 0时,f(0) = 0; 所以 ans = n
  • n % 4 == 1 时,由于(n - 1) % 4 == 0, n为奇数,所以 ans = f(n - 1) ^ n = (n - 1) ^ n = 1
  • n % 4 == 2 时,n为偶数,所以 ans = f(n - 1) ^ n = 1 ^ n = n + 1
  • n % 4 == 3 时,ans = f(n - 1) ^ n = (n - 1 + 1) ^ n = 0

所以,给定n,我们可以根据 n % 4 的值,求得“异或前缀和”

 int getsum(int x){
        switch(x % 4){
            case 0: return x;
            case 1: return 1;
            case 2: return x + 1;  
        }
        return 0;
    }

回到本题

题目大意是求:st ^ (st + 2) ^ (st + 4) ^ (st + 6) ^ (st + 8) ^ …(st + 2 * (n - 1))

经分析,这n项的奇偶性相同,都等同于st的奇偶

我们先只看最后一位
  • st为奇数时,每一项都是奇数
    1. n也为奇数,那么最低位异或的结果为1
    2. n为偶数,那么最低位异或的结果为0(偶数个1异或)
  • st为偶数时,最低位的异或结果为0

由上我们可知,当且仅当n & st & 1 == 1时(即n 和 st同奇时),最低位的结果为1,其他情况都是0,因此,我们可以记录一下,最低位的运算结果为b

然后让每一项都右移一位(相当于都除以2),令 s = st / 2 (下取整)
那么问题就转换成了求 s ^ (s + 1) ^ (s + 2) ^ (s + 3) … ^ (s + n - 1)

而上式 = (1 ^ 2 ^ 3 ^ 4 ^ …(s + n - 1)) ^ (1 ^ 2 ^ 3 ^ …(s - 1)) = getsum(s + n - 1) ^ getsum(s - 1),结果记为sum

那么最终的结果就是 (sum << 1) + b(或者 sum << 1 | b ) (因为sum是原式右移一位之后的异或结果,现在要左移回去)

最终代码

class Solution {
public:
	//计算异或前缀和
    int getsum(int x){
        int t = x % 4;
        switch(t){
            case 0: return x;
            case 1: return 1;
            case 2: return x + 1;  
        }
        return 0;
    }

    int xorOperation(int n, int start) {
        int b = n & start & 1;  //最低位结果
        int s = start >> 1;    
        int sum = getsum(s - 1) ^ getsum(s + n - 1);
        return (sum << 1) + b;
    }
};
  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值