解題說明
XOR Operation in an Array
題目描述:給定整數 n 和 start,定義一個長度為 n 的陣列 nums,其中 nums[i] = start + 2 * i(i 從 0 開始,即陣列元素為 start, start+2, start+4, ...)。回傳陣列中所有元素的 XOR 運算結果(nums[0] XOR nums[1] XOR ... XOR nums[n-1])。
解題思路:最直接的方法是直接模擬:建構陣列,逐一對每個元素做 XOR 累加。由於 n ≤ 1000,這完全在時間限制內。
進階思路:注意陣列元素為 start, start+2, start+4, ...,即一個等差數列,公差為 2。可以觀察 XOR 的數學規律:若 start 為偶數,所有元素最低位均為偶數(最低位為 0);XOR 的規律可以利用「1 XOR 2 XOR ... XOR k」的公式簡化計算。但對本題而言,直接模擬的 O(n) 已是最優,且程式碼最清晰。
C++ 解法
複雜度分析
時間複雜度:O(n)——迴圈執行 n 次,每次做一次乘法、加法和 XOR 運算,均為 O(1)。整體線性於輸入 n。
空間複雜度:O(1)——只使用一個累積變數 result,不需儲存整個陣列,空間為常數。
虛擬碼
1. Initialize result = 0. 2. For i from 0 to n-1: a. result = result XOR (start + 2 * i). 3. Return result.
其他解法
方法一:數學公式(O(1) 時間)
利用 XOR 前綴和公式 xorUpTo(k) 計算 0 XOR 1 XOR 2 XOR ... XOR k 的結果(規律為 {k, 1, k+1, 0} 依 k%4 循環),可在 O(1) 時間計算本題。由於 nums[i] = start + 2*i,所有元素最低位相同(均為 start & 1),可將問題拆解為「右移一位後的 XOR」加上最低位的貢獻,推導出 O(1) 公式。實作較複雜,面試中通常直接模擬即可。
方法二:生成陣列後 reduce(accumulate)
先建立完整的 nums 陣列,再用 std::accumulate 搭配 XOR 作為二元運算子一次性計算。時間 O(n),空間 O(n)(需額外陣列),功能等價於直接迴圈但多用空間,適合在串流計算框架中展示函數式風格。
方法三:SIMD 向量化(進階) 對大規模 n(如 n = 10^6),可用 CPU 的 SIMD 指令(SSE/AVX)同時對 4/8/16 個整數做 XOR,使吞吐量提升數倍。本題 n ≤ 1000,此方法無實際必要,但可作為效能優化的學習案例。
延伸思考
- 若公差從 2 改為任意整數
d,數學公式(O(1))的推導是否仍然可行?最低位的分析如何改變? - XOR 運算滿足交換律和結合律,在本題中可否更改元素計算順序(例如從後往前 XOR)得到相同結果?此性質在哪些演算法中有重要應用?
- 若將 XOR 換成 AND 或 OR,「等差數列的 AND/OR」是否有類似的 O(1) 封閉公式?難度如何比較?