LeetCode——89. 格雷編碼(JavaScript)
阿新 • • 發佈:2018-12-06
格雷編碼是一個二進位制數字系統,在該系統中,兩個連續的數值僅有一個位數的差異。
給定一個代表編碼總位數的非負整數 n,列印其格雷編碼序列。格雷編碼序列必須以 0 開頭。
示例 1:
輸入: 2
輸出: [0,1,3,2]
解釋:
00 - 0
01 - 1
11 - 3
10 - 2
對於給定的 n,其格雷編碼序列並不唯一。
例如,[0,2,3,1] 也是一個有效的格雷編碼序列。
00 - 0
10 - 2
11 - 3
01 - 1
示例 2:
輸入: 0 輸出: [0] 解釋: 我們定義格雷編碼序列必須以 0 開頭。 給定編碼總位數為 n 的格雷編碼序列,其長度為 2n。當 n = 0 時,長度為 20 = 1。 因此,當 n = 0 時,其格雷編碼序列為 [0]。
思路:
依次改變每位的0/1,看是否出現過,若出現過,則更新當前的數,並重新開始從第一位開始改變。
以 n=3 為例
設定一個 arr = [0,0,0],表示 0 的三位二進位制編碼,
設定一個set,用來儲存出現過的編碼,初始為 {’000‘},
設定一個res陣列,用來儲存結果序列,初始為 [0]
n = 3 時的格雷編碼序列長度應該為 2 的 3次方,即8.
當 res 長度小於 8 時開始迴圈,
while(res.length < 2 ** n) {
// 設定一個臨時變數,temp
let temp = arr.slice() // .slice()是拷貝,修改temp不會對arr造成影響
// 開始依次改變每一位
for (let i = 0; i < n; i++) {
temp[i] ^= 1 // 異或操作,1變0,0變1
let str = temp.join('') // str為二進位制編碼字串
若str在set中,則什麼都不發生,
若不在,則說明此編碼符合要求,要將此編碼加入set,還要計算此數字並加入res,最後更新arr為temp,break。
}
}
還要寫一個根據二進位制編碼求得數字的函式:
const strToNum = str => {
let num = 0
let len = str.length
for (let i = 0; i < len; i++) {
if (str[i] === '1') {
num += 2 ** (n-i-1)
}
}
return num
}
最終程式碼:
/**
* @param {number} n
* @return {number[]}
*/
var grayCode = function(n) {
const strToNum = str => {
let num = 0
let len = str.length
for (let i = 0; i < len; i++) {
if (str[i] === '1') {
num += 2 ** (n-i-1)
}
}
return num
}
let res = [0]
let arr = Array(n).fill(0)
let set = new Set()
set.add(arr.join(''))
while (res.length < 2 ** n) {
let temp = arr.slice()
for (let i = 0; i < n; i++) {
temp[i] ^= 1 // 異或操作,1變0,0變1
let str = temp.join('')
if (set.has(str)) {
temp[i] = arr[i] // 若已存在,則變回去
} else {
set.add(str)
res.push(strToNum(str))
arr = temp
break;
}
}
}
return res
};