掌握前綴表達式真的能夠隨心所欲!

題目地址(1310. 子數組異或查詢)

https://leetcode-cn.com/probl...java

題目描述

有一個正整數數組 arr,現給你一個對應的查詢數組 queries,其中 queries[i] = [Li, Ri]。

對於每一個查詢 i,請你計算從 Li 到 Ri 的 XOR 值(即 arr[Li] xor arr[Li+1] xor ... xor arr[Ri])做爲本次查詢的結果。

並返回一個包含給定查詢 queries 全部結果的數組。



示例 1:

輸入:arr = [1,3,4,8], queries = [[0,1],[1,2],[0,3],[3,3]]
輸出:[2,7,14,8]
解釋:
數組中元素的二進制表示形式是:
1 = 0001
3 = 0011
4 = 0100
8 = 1000
查詢的 XOR 值爲:
[0,1] = 1 xor 3 = 2
[1,2] = 3 xor 4 = 7
[0,3] = 1 xor 3 xor 4 xor 8 = 14
[3,3] = 8
示例 2:

輸入:arr = [4,8,2,10], queries = [[2,3],[1,3],[0,0],[0,3]]
輸出:[8,0,4,4]


提示:

1 <= arr.length <= 3 * 10^4
1 <= arr[i] <= 10^9
1 <= queries.length <= 3 * 10^4
queries[i].length == 2
0 <= queries[i][0] <= queries[i][1] < arr.length

暴力法

思路

最直觀的思路是雙層循環便可,果不其然超時了。python

代碼

class Solution:
    def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
         res = []
        for (L, R) in queries:
            i = L
            xor = 0
            while i <= R:
                xor ^= arr[i]
                i += 1
            res.append(xor)
        return res

前綴表達式

思路

比較常見的是前綴和,這個概念其實很容易理解,即一個數組中,第 n 位存儲的是數組前 n 個數字的和。c++

對 [1,2,3,4,5,6] 來講,其前綴和能夠是 pre=[1,3,6,10,15,21]。咱們能夠使用公式 pre[𝑖]=pre[𝑖−1]+nums[𝑖]獲得每一位前綴和的值,從而經過前綴和進行相應的計算和解題。其實前綴和的概念很簡單,但困難的是如何在題目中使用前綴和以及如何使用前綴和的關係來進行解題。數組

這道題是前綴對前綴異或,咱們利用了異或的性質 x ^ y ^ x = yapp

代碼

代碼支持 Python3,Java,C++:spa

Python Code:code

#
# @lc app=leetcode.cn id=1218 lang=python3
#
# [1218] 最長定差子序列
#

# @lc code=start


class Solution:
    def xorQueries(self, arr: List[int], queries: List[List[int]]) -> List[int]:
        pre = [0]
        res = []
        for i in range(len(arr)):
            pre.append(pre[i] ^ arr[i])
        for (L, R) in queries:
            res.append(pre[L] ^ pre[R + 1])
        return res

# @lc code=end

Java Code:blog

public int[] xorQueries(int[] arr, int[][] queries) {

        int[] preXor = new int[arr.length];
        preXor[0] = 0;

        for (int i = 1; i < arr.length; i++)
            preXor[i] = preXor[i - 1] ^ arr[i - 1];

        int[] res = new int[queries.length];

        for (int i = 0; i < queries.length; i++) {

            int left = queries[i][0], right = queries[i][1];
            res[i] = arr[right] ^ preXor[right] ^ preXor[left];
        }

        return res;
    }

C++ Code:ip

class Solution {
public:
    vector<int> xorQueries(vector<int>& arr, vector<vector<int>>& queries) {
        vector<int>res;
        for(int i=1; i<arr.size(); ++i){
            arr[i]^=arr[i-1];
        }
        for(vector<int>temp :queries){
            if(temp[0]==0){
                res.push_back(arr[temp[1]]);
            }
            else{
                res.push_back(arr[temp[0]-1]^arr[temp[1]]);
            }
        }
        return res;
    }
};

關鍵點解析

  • 異或的性質 x ^ y ^ x = y
  • 前綴表達式

相關題目

相關文章
相關標籤/搜索