LeetCode 題解 | 1442. 形成兩個異或相等數組的三元組數目(前綴和 位運算異或 C++)

題目描述(中等難度)

原題鏈接 代碼參考
在這裏插入圖片描述

算法1

(前綴和) O(n3)O(n^3)

一開始先寫了個三重循環,然後暴力算 i 到 j - 1 和 j 到 k 的異或結果,提交了下發現超時,後來想到了可以用前綴和來優化 (利用性質(a ^ b) ^ a = b;),最後順利 AC 了這個題

時間複雜度是O(n3)O(n^3),空間複雜度是O(n)O(n)

C++代碼

class Solution {
public:
    // 前綴和思想 (a ^ b) ^ a = b;
    int v[307];

    int countTriplets(vector<int> &arr) {
        int n = arr.size(), cnt = 0;

        v[0] = 0;
        for (int i = 1; i <= n; i ++) {
            v[i] = v[i - 1] ^ arr[i - 1]; // 下標存 1 開始,arr[i - 1]是第 i 個數
        }

        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                for (int k = j; k < n; k++) {
                    if ((v[i] ^ v[j]) == (v[j] ^ v[k + 1])) cnt ++;
                }
            }
        }
        return cnt;
    }
};

算法2

(位運算優化) O(n2)O(n^2)

算法 1 是利用了(a ^ b) ^ a = b;,藉助前綴和思想來解決

實際上a ^ b == 0 <--> a == b,所以只要枚舉左右端點 i k 即可。如果當前區間 [i,k][i, k] 的異或和是 0,那麼 j 有 k - i 種取值
在這裏插入圖片描述

時間複雜度是O(n2)O(n^2),空間複雜度是O(1)O(1)

C++代碼

class Solution {
public:
    int countTriplets(vector<int>& arr) {
        // a ^ b == 0 <--> a == b
        int n = arr.size(), res = 0;
        
        for (int i = 0; i < n; i ++) {
            int tmp = arr[i];
            for (int k = i + 1; k < n; k ++) {
                tmp ^= arr[k];
                if (tmp == 0) res += (k - i);
            }
        }

        return res;
    }
};

附:超時代碼

class Solution {
public:
    // 暴力超時
    int solve (int m, int n, vector<int> &arr) {
        int res = 0;
        for (int i = m; i <= n; i ++) {
            res ^= arr[i];
        }
        return res;
    }
    int countTriplets(vector<int> &arr) {
        int n = arr.size(), cnt = 0;
        for (int i = 0; i < n - 1; i++) {
            for (int j = i + 1; j < n; j++) {
                for (int k = j; k < n; k++) {
                    if (solve(i, j - 1, arr) == solve(j, k, arr)) cnt ++;
                }
            }
        }
        return cnt;
    }
};
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章