摘要:例如,也是一個有效的格雷編碼序列。示例輸入輸出解釋我們定義格雷編碼序列必須以開頭。給定編碼總位數為的格雷編碼序列,其長度為。因此,當時,其格雷編碼序列為。
LeetCode 89. 格雷編碼
格雷編碼是一個二進制數字系統,在該系統中,兩個連續的數值僅有一個位數的差異。
給定一個代表編碼總位數的非負整數 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]。
這題的難度主要是將給定的n轉化為格雷編碼
第一步 將n轉變為格雷編碼1=>["0","1"]
n = 1 0 1 n = 2 00 01 -- 11 10 n = 3 000 001 011 010 --- 110 111 101 100
分析上面的數字排列 我們可以注意到3點
以--為間隔上面的編碼與下面的編碼是軸對稱的(除了第一位以外)
后一個格雷編碼 是以上一個為基礎 做軸對稱生成,并且前一半編碼每項"0"+"xxx",后一半編碼每項"1"+"xxx",
每組的編碼的長度為2^n
先實現這部分邏輯
let make = (n) => { if (n === 1) { return ["0", "1"] } else { let pre = make(n - 1)//獲取上次的格雷編碼 let result = [] //存放結果 let max = Math.pow(2, n) - 1//當前n個最后一位的索引 for (let i = 0, len = pre.length; i < len; i++) { result[i] = `0${pre[i]}` result[max - i] = `1${pre[i]}` } return result } }
完整解題
let make = (n) => { if (n === 1) { return ["0", "1"] } else { let pre = make(n - 1)//獲取上次的格雷編碼 let result = [] //存放結果 let max = Math.pow(2, n) - 1//當前n個最后一位的索引 for (let i = 0, len = pre.length; i < len; i++) { result[i] = `0${pre[i]}` result[max - i] = `1${pre[i]}` } return result } } let grayCode = (n) => { if (n === 0) return [0] let arr = make(n) return arr.map(item => { return parseInt(item, 2) //parseInt(item,10)默認以十進制來換算 }) };
將二進制轉十進制 parseInt
parseInt(string, radix) String -> Number console.log(parseInt("11", 2));//返回一個數字 radix默認10 按照十進制解析 如果字符串的第一個字符不能轉為數字 將返回NaN
提到這個parseInt 就要提 toString
let num = 100; NumberObject.toString(radix); Number -> String console.log(num.toString(2));//返回一個字符串 radix默認10 按照十進制解析 "1100100"
最快的范例
他的思路其實也差不多 只是不采用遞歸的形式 比較直接 以1=>["0", "1"] 為基礎 生成目標格雷編碼
var grayCode = function (n) {//n=2 if (n === 0) return [0] const nums = ["0", "1"] const arr_splice = Array.prototype.splice for (let t = 2; t <= n; t++) { let args = nums.slice().reverse()//["1","0"] args.forEach((s, i) => args[i] = "1" + s)//["11","10"] args.unshift(0)//["0",11","10"] args.unshift(nums.length)//["2","0",11","10"] console.log(args) nums.forEach((s, i) => nums[i] = "0" + s)// ["00", "01"] arr_splice.apply(nums, args)// nums=> [ "00", "01", "11", "10" ] } return nums.map(binary => parseInt(binary, 2)) };
上面最關鍵步驟
const arr_splice = Array.prototype.splice ... args.unshift(0)//["0",11","10"] args.unshift(nums.length)//["2","0",11","10"] ... arr_splice.apply(nums, args)// nums=> [ "00", "01", "11", "10" ] ["00", "01"]+["11","10"] => [ "00", "01", "11", "10" ] 由于splice接受的是參數列表 arr.splice(2,0,"00","01") 不接受數組 所以巧妙的采用apply ,因為apply自身就是可以將集合的形式轉變為參數列表的形式 這也是call 與apply的區別之一
如果喜歡LeetCode或者更多數據結構的內容,可以戳這里,歡迎star
掃一掃 往期文章數據結構與算法-LeetCode 格雷編碼(No.89)
數據結構與算法-LeetCode 種花問題(No.605)
LeetCode-電話號碼的字母組合(No.17) 遞歸+hash
JavaScript 數據結構與算法 這題你會嗎?
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/109513.html
摘要:電話號碼的字母組合給定一個僅包含數字的字符串,返回所有它能表示的字母組合。給出數字到字母的映射如下與電話按鍵相同。注意不對應任何字母。 LeetCode 17. 電話號碼的字母組合 給定一個僅包含數字 2-9 的字符串,返回所有它能表示的字母組合。給出數字到字母的映射如下(與電話按鍵相同)。 注意 1 不對應任何字母。 showImg(https://user-gold-cdn.xit...
摘要:能否在不打破種植規則的情況下種入朵花能則返回,不能則返回。示例輸入輸出示例輸入輸出注意數組內已種好的花不會違反種植規則。輸入的數組長度范圍為。是非負整數,且不會超過輸入數組的大小。 LeetCode 605. 種花問題 假設你有一個很長的花壇,一部分地塊種植了花,另一部分卻沒有。可是,花卉不能種植在相鄰的地塊上,它們會爭奪水源,兩者都會死去。 給定一個花壇(表示為一個數組包含0和1,...
最近入職的公司主要做微信端的h5,所以在所難免要引用sdk。雖然官方文檔寫的還算清楚,但是還是有坑。 1.在index.html中 引入微信sdk 2.在assets/js 下新建文件 wx.js export default { wxShowMenu: function (that,sign=) { let url = window.location.href.split(#)[...
摘要:微信小程序圖片上傳阿里云服務器也折騰了蠻久才解決的,所以特意去記錄一下。上傳失敗第四步源碼在這里如果覺得這面文章對你有幫助的話,可給我點個這里,謝謝最后,希望這篇文章對你有所幫助,真真確確是可以在微信小程序中上傳圖片到阿里云的。 本人今年6月份畢業,最近剛在上海一家小公司實習,做微信小程序開發。最近工作遇到一個小問題。 微信小程序圖片上傳阿里云服務器Oss也折騰了蠻久才解決的,所以特意...
閱讀 2465·2021-09-09 09:33
閱讀 2865·2019-08-30 15:56
閱讀 3118·2019-08-30 14:21
閱讀 890·2019-08-30 13:01
閱讀 854·2019-08-26 18:27
閱讀 3584·2019-08-26 13:47
閱讀 3449·2019-08-26 10:26
閱讀 1583·2019-08-23 18:38