Back
Featured image of post xorQueries

xorQueries

Leetcode-1310

Leetcode 1310

今天又是爆肝的一天 , 感觉这个月应该 是异或月了,全是异或题(痛哭)

今天的每日一题是1310. 子数组异或查询

queries数组提供的是查询的范围

然后返回一个包含所有查询结果的数组

我们可以用类似 prefix sum 前缀和

采取 prefix XOR前缀异或 来完成该题

对于每个查询都要计算,因此我们应该优化每个查询的计算时间

queries(L , R)

= array[L] ⊕ …. ⊕ array[R] , 又 x ⊕ x = 0

= ( array[0] ⊕ …. ⊕ array[L - 1] ) ⊕ ( array[0] ⊕ …. ⊕ array[L - 1] ) ⊕ ( array[L] ⊕ …. ⊕ array[R] )

= ( array[0] ⊕ …. ⊕ array[L - 1] ) ⊕ ( array[0] ⊕ …. ⊕ array[R] )

= XORS[L] ⊕ XORS[R + 1]

XORS为存储 前缀异或 的数组 , 当L = 0时,XORS[0] = 0 ,以上等式仍然成立

数组不变,求区间 , 都可以用prefix来解决


public static int[] xorQueries(int[] arr, int[][] queries) {
    int n = arr.length;
    int[] pre = new int[n + 1];
    //计算每个位置的前缀和 pre[i] 表示前i项的异或和
    for (int i = 1; i <= n; i++) {
        pre[i] = pre[i - 1] ^ arr[i - 1];
    }
    int[] ans = new int[queries.length];
    int i = 0;

    /**
     * for (int i = 0; i < m; i++) {
     *    ans[i] = xors[queries[i][0]] ^ xors[queries[i][1] + 1];
     * }
     */

    for (int[] query : queries) {
        //前面多异或的部分,再重复异或一次就可以抵消了
        //假设 求 [1, 2],那么对于 [0, 2] 来说就是多异或了 [0, 0] 这个结果
        //根据 两个相同值异或结果为 0,那么我们可以再异或一次 [0, 0] 就将 [0, 0] 给抵消掉了
        //pre[query[0]]代表了[0, 0]异或 pre[query[1] + 1]代表了[0, 2]异或 其中[0, 0]异或两次
        //最后相当于[1, 2]异或
        ans[i++] = pre[query[0]] ^ pre[query[1] + 1];
    }
    return ans;
}

时间复杂度:O(n+m) , n , m 分别为array , queries数组的长度

空间复杂度:O(n)

类似题目有307. 区域和检索 - 数组可修改

Welcome to the world of Minezeratul