有一个笑话,世界上有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
通过三次称重咱们就能够找到较重的哪个小球了。
面对这种问题,其实解决思路都大通小异,都是须要找到问题关键状态,经过关键状态的数量咱们能够知道须要用到多少进制来解决问题。而后根据题目制定方案,来肯定每一位的状态码最终获得结果。