头图

Algorithm (6)-Array XOR Operation

Array XOR operation

Official Problem Solution L6

1. Title

Array XOR operation

Easy difficulty 83

Give you two integers, n and start .

The array nums defined as: nums[i] = start + 2*i (subscript starts from 0) and n == nums.length .

Please return nums all elements in the bitwise exclusive OR ( the XOR results) obtained.

Example 1:

输入:n = 5, start = 0
输出:8
解释:数组 nums 为 [0, 2, 4, 6, 8],其中 (0 ^ 2 ^ 4 ^ 6 ^ 8) = 8 。
     "^" 为按位异或 XOR 运算符。

example 2:

输入:n = 4, start = 3
输出:8
解释:数组 nums 为 [3, 5, 7, 9],其中 (3 ^ 5 ^ 7 ^ 9) = 8.

example 3:

输入:n = 1, start = 7
输出:7

Example 4:

输入:n = 10, start = 5
输出:2

prompt:

  • 1 <= n <= 1000
  • 0 <= start <= 1000
  • n == nums.length

2. Solution

2.1 Method 1: Simulation

Idea

Just simulate according to the meaning of the question:

code

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

complexity analysis

  • Time complexity: O ( n ). Here we use a loop to numbers 1609d22db57503 n
  • Space complexity: O (1). Only constant-level auxiliary space is used here.

2.2 Method 2: Mathematics

Denoted ⊕ is the exclusive OR operation, and the exclusive OR operation satisfies the following properties:

  1. xx=0;
  2. x y = y x (commutative law);
  3. ( X Y ) ⊕ Z = X ⊕ ( Y Z ) (associative law);
  4. x y y = x (reflexivity);
  5. i Z , there are 4 i ⊕(4 i +1)⊕(4 + i

In this problem, we need to calculate Start ⊕ ( Start +2 I ) ⊕ ( Start +4 I ) ⊕ ⋯ ⊕ ( Start +2 ( n- -1)).

Observing the formula, we can know that the parity of these numbers is the same, so the lowest bits in their binary representations are either all 1s or all 0s. So we can extract the lowest bit of the binary digits of the number involved in the operation for separate processing. If and only if start is an odd number, and n is also an odd number, the lowest bit of the binary bit of the result is 1.

In this case we can be converted to the formula ( S ⊕ ( S + 1'd) ⊕ ( S +2) ⊕ ⋯ ⊕ ( S + n- -1)) × 2 + E , s = start /2, e represents the lowest bit of the operation result. That is, we deal with the lowest digit separately, and the number sequence after the lowest digit is discarded becomes a series of continuous integers.

In this way, we can describe a function sumXor ( x ), which means 0⊕1⊕2⊕...⊕ x . Using the property of XOR operation 5, we can reduce the complexity of calculating the function to O (1), because the result of the XOR of four consecutive integers starting i x ) can be expressed as:

$$ \text{sumXor}(x)= \begin{cases} x,& x=4k,k\in Z\\ (x-1) \oplus x,& x=4k+1,k\in Z\\ (x-2) \oplus (x-1) \oplus x,& x=4k+2,k\in Z\\ (x-3) \oplus (x-2) \oplus (x-1) \oplus x,& x=4k+3,k\in Z\\ \end{cases} $$

We can further simplify the formula:

$$ \text{sumXor}(x)= \begin{cases} x,& x=4k,k\in Z\\ 1,& x=4k+1,k\in Z\\ x+1,& x=4k+2,k\in Z\\ 0,& x=4k+3,k\in Z\\ \end{cases} $$

So the final result can be expressed as:

$$ (\text{sumXor}(s-1) \oplus \text{sumXor}(s+n-1))\times 2 + e) $$

code

class Solution {
    public int xorOperation(int n, int start) {
        int s = start >> 1;
        // int mod = start % 2;
        // int e = (n & 1) == 1 ? mod : 0;
        int e = n & start & 1;
        int ret = sumXor(s - 1) ^ sumXor(s + n - 1);
        return ret << 1 | e;
    }

    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;
    }
}

complexity analysis

  • Time complexity: O (1). We only need a constant time to calculate the result.
  • Space complexity: O (1). We only need constant space to store several variables.

3. Thinking

  1. First of all, the first two items in the following calculation formula use the idea of prefix sum, namely

    $$ \begin{cases} \text{sumXor}(s-1)\quad\quad\ = 0 \oplus 1 \oplus 2 \oplus ··· \oplus {(s-2)} \oplus {(s-1)}\\ \text{sumXor}(s+n-1)) = 0 \oplus 1 \oplus 2 \oplus ··· \oplus {(s-2)} \oplus {(s-1)} \oplus {(s)} \oplus {(s+1)} \oplus ···\oplus {(s+n-2)}\oplus {(s+n-1)} \end{cases} $$

    Therefore, according to property 1, when these two items are XORed, it is equivalent to the subtraction of the prefix sum, namely:

$$ \text{sumXor}(s-1) \oplus \text{sumXor}(s+n-1) =[0 \oplus 1 \oplus ··· \oplus {(s-1)}] \oplus [0 \oplus 1 \oplus ··· \oplus {(s-1)} \oplus {s} \oplus ···\oplus {(s+n-2)}\oplus {(s+n-1)}] \\ \quad\quad \quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad\quad =[0 \oplus 0 \oplus 1 \oplus 1 \oplus ··· \oplus {(s-1)} \oplus {(s-1)}] \oplus {s} \oplus ···\oplus {(s+n-2)}\oplus {(s+n-1)} \\ \quad\quad \quad\quad \quad\quad \quad\quad \quad\quad \quad\quad \quad\quad = {s} \oplus {(s+1)} \oplus···\oplus {(s+n-2)}\oplus {(s+n-1)} $$

  1. For the e , it is for the following reasons:

    For binary numbers, because each time start added to 2 , the last digit of all the binary numbers in the resulting array is always the same, that is, if start is an even number, then All numbers in the array are even numbers, and the last digit is all 0. If it is odd, all numbers in the array are odd numbers, and the last digit is all 1.

    Therefore, it can be seen that only when start is an odd number and n is an odd number, the last digit of e can be 1, and all other cases are 0.

    And because we only need the last digit, we also need to bitwise and up 1. That is: n & start & 1

  2. Combining thinking 1 and thinking 2, we can generalize the topic, namely:

    Here are three integers, n , start and k .

    The array nums defined as: nums[i] = start + k*i (i starts from 0, k=2^m (m>=1)) and n == nums.length .

    Please return nums all elements in the bitwise exclusive OR ( the XOR results) obtained.

    The solution to the problem is the same as above, the result result can be expressed as:

    $$ result =\text{sumXor}(s-1) \oplus \text{sumXor}(s+n-1))\times k + e \\ 其中 s=\lfloor \frac{\textit{start}}{k} \rfloor,e=(start \% k) \oplus (start \% k) \oplus ···\oplus(start \% k)\oplus(start \% k) $$

    And the above e is equal to the exclusive OR of n start to the remainder of k, you can refer to consider 2 and property 1, and we get

    int mod = start % k;
    int e = (n & 2 == 1) ? mod : 0;

莫小点还有救
219 声望26 粉丝

优秀是一种习惯!