LeetCode周赛 | 1486一个位运算easy题目的数学解法,时间空间都O(1)

传送门 1486. 数组异或操作

思路整理自题解,下面是本菜鸡的新手版= =

按位异或的性质

  1. x ⊕ x = 0
  2. x ⊕ 0 = x
  3. x ⊕ x+1 = 1,x为偶数(二进制最低位为0)。

推导

  • 通项start+2i,需计算result = start ⊕ start+2 ⊕ start+4 ⊕ start+6 ⊕ … ⊕ (start + 2(n-1))
  • 观察上式,若全部项右移一位(除以2)变形为类似3.,则对应答案也右移一位。result/2 = start/2 ⊕ start/2+1 ⊕ start/2+2 ⊕ start/2+3 ⊕ … ⊕ (start/2 + (n-1)),start/2需要分奇偶讨论:
若start/2为偶数

上述结果可以进一步归纳:

  • n-1%4 == 1或3,即n为偶数时,n%4 == (00)B 或 (10)Bresult/2 = n的右起第二位 = (n>>1)&1
  • n-1%4 == 0或2,即n为奇数时,n%4 == (01)B 或 (11)Bresult/2 = st/2 + n - 1 + (n>>1)&1
若start/2为奇数

result/2
= (start/2-1 ⊕ start/2-1) ⊕ start/2 ⊕ start/2+1 ⊕ start/2+2 ⊕ start/2+3 ⊕ … ⊕ (start/2 + (n-1))
= start/2-1 ⊕ [start/2-1 ⊕ start/2 ⊕ start/2+1 ⊕ start/2+2 ⊕ start/2+3 ⊕ … ⊕ (start/2 + (n-1))]
x ⊕ x = 0start/2-1 ⊕ start/2-1 = 0;由x ⊕ 0 = x,上述变形成立。[]内又可以利用3.计算(类似偶数的情况)。

  • result/2左移一位,补上最低位即可。
    现在来看变形前的式子:result = start ⊕ start+2 ⊕ start+4 ⊕ start+6 ⊕ … ⊕ (start + 2(n-1))
    • 若start为偶数(二进制最低位0),result最低位必为0。
    • 若start为奇数,则上式中所有项start + 2i都为奇数(二进制最低位0),再次分类讨论:n为奇数时,最低位是奇数个1异或,得1;n为偶数时,最低位是偶数个1异或,得0。取n的二进制最低位即可。

实现

双100%

class Solution {
    //half_start is even
    int half_res(int n, int half_start) {
        return n % 2 ? (half_start + n - 1 + ((n/2)&1)):((n/2)&1);
    }
public:
    int xorOperation(int n, int start) {
        int half;
        if(start / 2 % 2) { // odd
            half = (start/2 - 1) ^ half_res(n + 1, start/2 - 1);
        } else { // even
            half = half_res(n, start/2);
        }
        return half*2 + (start%2 ? (n&1) : 0);
    }
};

你可能感兴趣的:(LeetCode周赛 | 1486一个位运算easy题目的数学解法,时间空间都O(1))