用XOR還原陣列 Find The Original Array of Prefix XOR Leetcode 2433

更新於 發佈於 閱讀時間約 3 分鐘

題目敘述

題目會給我們一個輸入陣列,陣列裡面存放的是每個元素做XOR之後的前綴累積值

要求我們從累積值還原出原本的陣列元素值

XOR前綴累積值定義:

pref[i] = arr[0] ^ arr[1] ^ ... ^ arr[i]

詳細的題目可在這裡看到


測試範例

Example 1:

Input: pref = [5,2,0,3,1]
Output: [5,7,2,3,2]
Explanation: From the array [5,7,2,3,2] we have the following:
- pref[0] = 5.
- pref[1] = 5 ^ 7 = 2.
- pref[2] = 5 ^ 7 ^ 2 = 0.
- pref[3] = 5 ^ 7 ^ 2 ^ 3 = 3.
- pref[4] = 5 ^ 7 ^ 2 ^ 3 ^ 2 = 1.

Example 2:

Input: pref = [13]
Output: [13]
Explanation: We have pref[0] = arr[0] = 13.

約束條件

Constraints:

  • 1 <= pref.length <= 105
  • 0 <= pref[i] <= 106

演算法

其實這題同樣運用到XOR運算子Self inverse的性質

A ⊕ A = 0

依照題目定義

pref[i] = arr[0] ^ arr[1] ^ ... ^ arr[i]


我們可以知道

pref[0] = arr[0] 恰好是首項


接著

pref[1] = arr[0] ^ arr[1] 利用Self inverse的性質

計算pref[1] ^ pref[0] = (arr[0] ^ arr[1]) ^ arr[0] = arr[1]

還原出第二項 arr[1]


同理類推

計算pref[2] ^ pref[1] = (arr[0] ^ arr[1] ^ arr[2]) ^ (arr[0] ^ arr[1] )= arr[2]

還原出第三項 arr[2]


可以歸納出一個規律

arr[i] = pref[i] & pref[i-1]

由這個規則,去還原原始陣列元素值即可。



程式碼

class Solution:
 def findArray(self, pref: List[int]) -> List[int]:
  
  # Utilize the property of self-inverse
  # Self-inverse : A ⊕ A = 0
  # This means that any value XOR’d with itself gives zero.
  
  origin = [ pref[0] ]
  
  for i in range(1, len(pref)):
   
   origin.append( pref[i]^pref[i-1] )
  
  return origin

複雜度分析

時間複雜度:

O( n ) 迴圈迭代長度為O(n),和原本的陣列一樣長。

空間複雜度:

O( n ) out-of-place update創造了一個origin array,和原本的陣列長度一樣長。


關鍵知識點

學完這題之後,記得吸收沉澱一下,
回去複習 Single NumberFind the difference 這兩題喔,背後用到的都是同樣的觀念,也都用到 XOR 運算子 Self-inverse的成雙成對互相消去的特質。


Reference:

[1] Python/JS/Go/C++ O(n) by XOR self-inverse [w/ Hint] - Find The Original Array of Prefix Xor - LeetCode

avatar-img
91會員
425內容數
由有業界實戰經驗的演算法工程師, 手把手教你建立解題的框架, 一步步寫出高效、清晰易懂的解題答案。 著重在讓讀者啟發思考、理解演算法,熟悉常見的演算法模板。 深入淺出地介紹題目背後所使用的演算法意義,融會貫通演算法與資料結構的應用。 在幾個經典的題目融入一道題目的多種解法,或者同一招解不同的題目,擴展廣度,並加深印象。
留言0
查看全部
avatar-img
發表第一個留言支持創作者!
題目會給定一組規則,要求我們計算給定長度下的母音直線排列有幾種?
題目會給定一個存有整數的陣列,要求我們依照下列規則進行排序,由小排到大,升序排列。
題目會給定一個帶有Random Pointer的鏈結串列,要求我們實體複製deep copy這條鏈結串列,並且輸出副本的根結點。
題目給定一個規律變化的二進位字串,問我們第N排,第K個bit是多少? 變化的規律: 上一排的0到下一排展開成01,上一排的1到下一排展開成10 第一排初始化是0 第二排是01 第三排是0110 第四排是01101001 ...其餘依此類推 詳細的題目可在這裡看到
題目會給我們一顆二元樹的根結點,要求我們找出每一層最大的節點值。
這題的題目會給我們一個輸入整數,要求我們判斷這個整數是否可以用4^k 的形式來表達?
題目會給定一組規則,要求我們計算給定長度下的母音直線排列有幾種?
題目會給定一個存有整數的陣列,要求我們依照下列規則進行排序,由小排到大,升序排列。
題目會給定一個帶有Random Pointer的鏈結串列,要求我們實體複製deep copy這條鏈結串列,並且輸出副本的根結點。
題目給定一個規律變化的二進位字串,問我們第N排,第K個bit是多少? 變化的規律: 上一排的0到下一排展開成01,上一排的1到下一排展開成10 第一排初始化是0 第二排是01 第三排是0110 第四排是01101001 ...其餘依此類推 詳細的題目可在這裡看到
題目會給我們一顆二元樹的根結點,要求我們找出每一層最大的節點值。
這題的題目會給我們一個輸入整數,要求我們判斷這個整數是否可以用4^k 的形式來表達?
你可能也想看
Google News 追蹤
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇內容,將會講解什麼是陣列,以及與陣列相關的知識。包括陣列的簡介、陣列的資料限制、陣列的維度、一維陣列、二維陣列。
Thumbnail
在比賽裡這就是大家拚手速的題目了,準備好了嗎?
※ 常用arry型態的方法: 長度: length 查詢第N個元素: [] 查詢元素在第N個: indexOf( ) 判斷是否為array: isArray() 新增和刪除: push():新增後面的數值 unshift():新增前面的數值 pop():刪除後面的數值 sh
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
今天要來嘗試的是,如何不用好用的Array.map 方法,來實現 Array.map 的功能。 What is Array.map map() 方法會建立一個新的陣列,其內容為原陣列的每一個元素經由回呼函式運算後所回傳的結果之集合。 簡單來說就是把陣列內的每一個值,個別跑函式,把新的值回傳出成
(略),array 是用來將陣列的值進行累加,我們來看看怎麼怎麼達成吧: Given an integer array nums, a reducer function fn, and an initial value init, return the final result obtained
Thumbnail
嘿,大家新年快樂~ 新年大家都在做什麼呢? 跨年夜的我趕工製作某個外包設計案,在工作告一段落時趕上倒數。 然後和兩個小孩過了一個忙亂的元旦。在深夜時刻,看到朋友傳來的解籤網站,興致勃勃熬夜體驗了一下,覺得非常好玩,或許有人玩過了,但還是想寫上來分享紀錄一下~
Thumbnail
這篇內容,將會講解什麼是陣列,以及與陣列相關的知識。包括陣列的簡介、陣列的資料限制、陣列的維度、一維陣列、二維陣列。
Thumbnail
在比賽裡這就是大家拚手速的題目了,準備好了嗎?
※ 常用arry型態的方法: 長度: length 查詢第N個元素: [] 查詢元素在第N個: indexOf( ) 判斷是否為array: isArray() 新增和刪除: push():新增後面的數值 unshift():新增前面的數值 pop():刪除後面的數值 sh
Thumbnail
分享在網路上看到的陣列題目。通常 for...of 的 value 是陣列中的每個值,那如果我們在迭代中對陣列操作會發生什麼事? 題目來源:https://x.com/_jayphelps/status/1774640511158022335?s=20
今天要來嘗試的是,如何不用好用的Array.map 方法,來實現 Array.map 的功能。 What is Array.map map() 方法會建立一個新的陣列,其內容為原陣列的每一個元素經由回呼函式運算後所回傳的結果之集合。 簡單來說就是把陣列內的每一個值,個別跑函式,把新的值回傳出成
(略),array 是用來將陣列的值進行累加,我們來看看怎麼怎麼達成吧: Given an integer array nums, a reducer function fn, and an initial value init, return the final result obtained