1442.形成两个异或相等数组的三元组数目

题目描述:

image.png


解:

形如arr[i] op arr[i+1] … op arr[j-1]的情况,都可以考虑用前缀和的方式来优化数组,当然,这里并非是前缀和而是前缀异或。
前缀和的容斥是用减法实现的,前缀异或的容斥是用一个数异或本身等于0这个性质来实现。
所以,我们先将原数组O(n)的处理成前缀异或数组。
然后开始暴力…(其实还可以继续优化的)
遍历i,j,k,用 xor[j-1] ^ xor[i-1] 来表示 arr[i]^arr[i+1]...^arr[j-1] ,也就是a,同理可得b
代码如下:

  1. class Solution {
  2. public int countTriplets(int[] arr) {
  3. int n = arr.length;
  4. int[] xor = new int[n];
  5. xor[0] = arr[0];
  6. for(int i=1; i<n; i++) {
  7. xor[i] = xor[i-1] ^ arr[i];
  8. } //arr[0 - i]
  9. int ans = 0,a,b;
  10. for(int i = 0; i < n; i++) {
  11. for(int j=i+1; j < n; j++) {
  12. for(int k = j; k < n; k++) {
  13. if(i==0) { //xor数组应该多开一位避免特判的,忘了...orz
  14. a = xor[j-1];
  15. } else {
  16. a = xor[j-1] ^ xor[i-1];
  17. }
  18. b = xor[k] ^ xor[j-1];
  19. if(a==b) ans++;
  20. }
  21. }
  22. }
  23. return ans;
  24. }
  25. }

抄大佬的100%题解:

  1. public int countTriplets(int[] arr) {
  2. //所有可能的组合
  3. int total = 0;
  4. int length = arr.length;
  5. //判断数组从i到j的元素异或结果是否是0
  6. for (int i = 0; i < length - 1; i++) {
  7. int xor = arr[i];
  8. for (int j = i + 1; j < length; j++) {
  9. xor ^= arr[j];
  10. //如果数组从i到j的异或结果是0,那么他们
  11. //可能的组合就是j-i
  12. if (xor == 0) {
  13. total += (j - i);
  14. }
  15. }
  16. }
  17. return total;
  18. }