有一個笑話,世界上有10種人,一種是看得懂二進制的,一種是看不懂的。 若是你看懂了這個笑話,這篇文章就是適合你讀的了javascript
leetcode 上有一道這樣的題,Single Number,題目是要你要找到數組中惟一隻存在一個的數字,其餘數字都出現兩次。這道題目很是的簡單,咱們能夠用 hash 表來記錄全部數字的次數,而後找到次數爲1的那個數字。若是用二進制來解決這道題效率會快不少。java
二進制中有一個操做符叫作位異或,他的做用是兩個位數字相同則爲0,不一樣則爲1,即 1^1=0,0^0=0,1^0=1,0^1=1;數組
經過這個運算符的特色咱們能夠知道,任何一個數對本身位異或操做,獲得的結果都是 00000000,00000000對任意數字位異或獲得的都是那個數字。而且 A ^ B ^ C = C ^ B ^A,這個操做符是知足交換律的。下面看一下 js 的簡單解法:spa
/** * @param {number[]} nums * @return {number} */
var singleNumber = function(nums) {
return nums.reduce((res, cur) => res ^ cur);
};
複製代碼
有 8 個如出一轍的瓶子,其中有 7 瓶是普通的水,有一瓶是毒藥。任何喝下毒藥的生物都會在一星期以後死亡。如今,你只有 3 只小白鼠和一星期的時間,如何檢驗出哪一個瓶子裏有毒藥?code
咱們用二進制給每瓶水進行編號,編號分別爲,000,001,010,011,100,101,110,111,分別對應1-8的瓶子,而後讓第一隻老鼠喝第一位爲1的,第二隻老鼠喝第二位爲1的,第三隻老鼠喝第三位爲1的,假設第四瓶水有毒,即011有毒ip
根據死亡結果,恰好是第四瓶水011,這只是一個巧合嗎,恐怕不是的,咱們能夠用數學的思惟來證實一下這個問題leetcode
每隻老鼠喝了毒藥只會出現兩種狀況死或者不死,一隻老鼠能夠驗證兩瓶藥有沒毒,即2^1,兩隻老鼠能夠驗證2^2瓶藥,三隻老鼠能夠驗證2^3瓶藥,那麼要怎麼去驗藥呢get
有 1000 個如出一轍的瓶子,其中有 999 瓶是普通的水,有一瓶是毒藥。任何喝下毒藥的生物都會在一星期以後死亡。如今,你只有 10 只小白鼠和一星期的時間,如何檢驗出哪一個瓶子裏有毒藥?數學
根據上面的問題,咱們可以知道 2 ^ 10 = 1024 > 1000,也是經過對每一個瓶子進行二進制編號便可檢驗出哪一個瓶子有毒。hash
如今,有意思的問題來了:若是你有兩個星期的時間,爲了從 1000 個瓶子中找出毒藥,你最少須要幾隻老鼠?注意,在第一輪實驗中死掉的老鼠,就沒法繼續參與第二次實驗了。
咱們要達到的目的是用盡量少的老鼠,在兩週以內找到結果,因此咱們必需要進行兩輪的實驗,那麼每隻老鼠可能就會出現三種狀況,第一輪死掉,第二輪死掉,第二輪活着,上面一題老鼠會出現兩種狀況用的是二進制,那麼這一題很明顯咱們須要用到三進制。3 ^ 6 = 729, 3 ^ 7 = 2187, 很明咱們至少是須要7只老鼠。
27個小球。其中一個比其餘小球都要重一點。給你一個天平,最多稱3次,找出這個特殊的小球。
這題也是須要用到三進制的思路來解決的,咱們每次稱可能出現三種狀態左邊重,右邊重,同樣重,3 ^ 3 恰好27,因此咱們是能夠在3次內找到這個小球。
先給每一個球編號000,001,002,010,...,222
通過三次稱重咱們就能夠找到較重的哪個小球了。
面對這種問題,其實解決思路都大通小異,都是須要找到問題關鍵狀態,經過關鍵狀態的數量咱們能夠知道須要用到多少進制來解決問題。而後根據題目制定方案,來肯定每一位的狀態碼最終獲得結果。