前一段时间,我们介绍了LeetCode上面的一个经典算法题【两数之和问题】。 这一次,我们把问题做一下扩展,尝试在数组中找到和为“特定值”的三个数。 题目的具体要求是什么呢?...我们随意选择一个特定值,比如13,要求找出三数之和等于13的全部组合。...小灰的思路,是把原本的“三数之和问题”,转化成求n次“两数之和问题”。 ?...因此我们成功找到了一组匹配的组合:1,3,9 但这并不是结束,我们要继续寻找其他组合,让指针k继续左移: ? 计算两指针对应元素之和,3+7 = 10找到的组合重复,因此我们直接结束本轮循环。 第2轮,访问数组的第2个元素2,把问题转化成从后面元素中找出和为11(13-2)的两个数。
&运算 &运算通常用于二进制取位操作,例如一个数 & 1 的结果就是取二进制的最末位。这可以用来判断一个整数的奇偶,二进制的最末位为 0 表示该数为偶数,最末位为 1 表示该数为奇数。 2....|运算 |运算通常用于二进制特定位上的无条件赋值,例如一个数 or 1 的结果就是把二进制最末位强行变成 1。...^运算 ^运算通常用于对二进制的特定一位进行取反操作,因为异或可以这样定义:异或 0 都不变,异或 1 则取反。...使用~运算时要格外小心,你需要注意整数类型有没有符号。如果~的对象是无符号整数(不能表示负数),那么得到的值就是它与该类型上界的差,因为无符号类型的数是用0000 到FFFF 依次表示的。 5....想办法用»代替除法运算可以使程序效率大大提高。
如同芸芸众生中的千人千面,全世界使用的语言如此之多,肯定有其独特之处。 不过这里说的复杂语言,是从计算机显示文字的角度来讲的。在计算机系统里,文字都是以二进制编码存储的。...当需要在屏幕上显示某个文字的时候,就由字库引擎以对应的编码在字体文件中找到对应的图形,然后将图形输出到屏幕上,就完成了文字的显示。这个过程中,编码与图形是一一对应的,关系比较简单。...下图用黑色表示原本的字母字形,而用不同颜色表示了同一个字母在词首、词中、词尾的不同字形。 例1 在另外一些语言中,部分字形会根据其组合的字符发生变化。...如下面缅甸语的例子,一个字母包裹在另一个字母外。并且会随着包裹字母的不同而变化。 例2 比如连字 在有的语言里,当特定序列的字母出现的时候,会组合成一个全新的字形。...那有没有什么办法可以让不懂语言的人在某些情况下,也能操作一把快速检查呢? 试试使用华为的多语言服务吧。
最近一个需求需要使用golang实现一个兼容redis的无压缩的bitmap,需要提供一个bitcoun函数来统计这个bitmap中二进制位1的个数,查了一圈并没有找到类似的第三方库,因此决定自己实现一个...问题简化 问题本质实际就是给定一个数字,比如一个二进制数10101101,计算出这个数字中二进制位1的个数,对于10101101这个数字来说它有5个位为1,即:10101101 对于这个问题,最简单的办法就是挨位数...,不过这个办法太笨了,没有逼格。...那么有没有银弹呢?答案是肯定的,而且还不止一种。 2....1的个数 8位数字计算过程与4位计算过程本质是相同的,都是拆解组合,伪代码如下: func OnesCount8(x uint8) int { x = x & 0b01010101 + x >>
因为古代人是掰手指计数的,人类刚好有十个手指,所以就用十进制,如果人类有十二个手指,那么我们肯定就用十二进制了。 几乎所有的文明都采用了十进制,那么有没有文明采用二十进制呢?...image.png 所以说,不是计算机想用二进制表示,而是计算机没办法,只能用二进制表示。那么二进制是不是没有十进制优秀呢?...不能这么粗暴的比较,但是简单的东西往往更高级,我们现在用电脑看的网页,听得音乐,看的视频,玩的游戏,这背后的一切信息都是一串串0和1的组合变化而来,是不是很神奇?...二进制就是一位最多表数两个数:0和1(十进制一位最多表示十个数:0~9),如果要表示数字2,一位就表示不下了,要进一位变成两位变成10,二进制的10就等于十进制的2。...想来想去都想不到啊,不知道你有没有发现,计算机是没有减法运算的,计算机的减法是通过加法实现的,那么加法怎么能达到减法的效果呢?
要完成的函数: int findComplement(int num) 说明: 1、这道题目要找出一个正整数(32位)所有不含前导零的位的相反数。比如5-101-010-2,2就是5的补数。...2、这道题目按照传统思路是,逐位处理原来的数,通过不断的“>>”,输出最后一位的数,然后这个数取反再乘以一个系数,最后求和,输出就是我们要的数。 如何判断当前已取到了所有不含前导零的数?...只需要不断除以2,比如5/2=2,2/2=1,1/2=0,最后为0才停下,一共有三次除法,也就有三个不含前导零的数位。 这样子这道题也可以做,但是太慢了。我们再看看有没有更直接的办法。...3、我们发现5的补数是2,那么5+2=7=111(二进制),1的补数是0,1+0=1=1(二进制)。...我们已知有多少个不含前导零的数位,那么我们可以构造出7来,比如5有3个数位,那么7就是pow(2,3)-1;比如1有1个数位,那么1就是pow(2,1)-1 至此,我们找到了更好更直接的方法去处理。
大家觉得上面这个办法怎么样?我们按照题目要求完成了任务。 但是,这个办法是受限的。如果两个整数太大的话相加会溢出,那有没有完美的办法呢?...既然这样问,那答案肯定是有的,办法就在我们上面新学到的知识中。 方法三:使用异或操作符 不知道你第一次看到这个代码的时候有没有懵逼呢?反正我是挺惊讶的。...例题2:编写代码求一个整数存储在内存中的二进制中1的个数 方法一:我们可以想办法拿到二进制的每一位,然后统计1的个数。...这种算法除非见过,一般人还真想不出来,不过我们记住就行,不必太执着其中的原理。 例题3:判断一个数是不是2的次方数 2的次方数,有没有什么特点呢?...我们知道2的次方数二进制表示中只有一个1,而 n &= (n - 1) 这个式子执行一次,二进制表示的数就会少一个1,那如果 n &= (n - 1) 等于0的话,不就说明 n 是2的次方数吗?
但是这样时间复杂度跟空间复杂度都在O(n),而且这么做太简单了,怎么办,还有没有其它解法? 我们回想一下异或运算符的特性,两个操作数相同的话为0,任何数与0做异或的结果还是那个数。...那么怎么找到这不一样的位置呢?还记得位运算的特性,0跟1做运算下来还是1,我们从右向左依次跟1做与运算,就能找到它了。...注意,除 N = 0 外,任何二进制表示中都不含前导零。二进制的反码表示是将每个 1 改为 0 且每个 0 变为 1。例如,二进制数 "101" 的二进制反码为 "010"。...给你一个十进制数 N,请你返回其二进制表示的反码所对应的十进制整数。...总而言之,这类的题型其实很固定,一堆数里找特定的数啊,一个数的特定变形啊,我们只要关注异或运算那三种特性,那解题就没有太大障碍了。
以此类推,为了实现对n位二进制数据的加法,需要使用n个全加器芯片,并且依次把进位传到下一个全加器。同理,我们可以通过任意位的加法器来实现对于较长二进制数的计算。...在这个过程中,需要不断地把数据操作过程在计算机外记录下来,那么有没有办法让计算过程自动进行呢?答案是肯定的。 首先,我们需要一个叫做内存的东西,它能够把数据存储在计算机里面,并且能够保持一定的时间。...关于内存的实现,除了上述提到的基本逻辑门的组合(组合逻辑)以外,还需要加上触发器设计(涉及时序逻辑)实现。 ? 下图是一个在内存中计算求和的过程。...为了表示方便,我们已经把里面关于二进制的表述都换成了我们较为熟悉的十进制,实际上在计算机里面存储的都是二进制。...5.1 输出 为了使从1到100的计算结果能够显示在计算机屏幕上,我们需要在内存中留出特定的区域存放用于显示的内容,在CPU通过指令的运行把数据存放在特定的内存位置上以后,操作系统负责不断地将这些特定区域的内容在屏幕上显示出来
应用 这个操作最常见的应用就是在二分法、折半等这些需要找到中间值的时候,而且不用担心被除数是奇数、商带小数、除数为0等异常情况,使用位移操作可以尽可能的避免这些异常的处理,减少系统的异常情况 或 | 通常用于二进制特定位上的无条件赋值...这可以用来判断一个整数的奇偶,二进制的最末位为0表示该数为偶数,最末位为1表示该数为奇数。...使用not运算时要格外小心,你需要注意整数类型有没有符号。如果not的对象是无符号整数(不能表示负数),那么得到的值就是它与该类型上界的差,因为无符号类型的数是用$0000到$FFFF依次表示的。...1010 [非.png] 异或 ^ 通常用于对二进制的特定一位进行取反操作,因为异或可以这样定义:0和1异或0都不变,异或1则取反。...理论应用 前面说道在位计算中的几个特性,将这些特性组合起来的效果,可以分为几点: 求值 取权重 n & 1位运算等价于n%2取余运算 其实本质上也是求除以2之后的余数,事实上这个操作可以得到n的二进制表示的最低位
释义 给定一个整数数组 nums ,找到一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。...分析 题目意思应该比较清晰了,我们也能很快想到一种方法,那就是计算所有可能的组合,然后比较所有组合的结果,选出结果最大的那个即可。...这确实是一个可行的犯法,但是当数组越来越大时,其组合的可能性也越来越多,这显然是一个很低效的算法。那么有没有更好的办法呢?有!...既然我们已经知道前面部分的最大子序列和,如果前部分最大子序列和小于0,则加上一个数,将会小于这个数。所以当前最大数就是当前数,否则的话,当前最大数是前部分的序列和加上该数。...再将当前数与之前的最大和比较,取较大值即可,直到遍历所有数,找到最终的最大序列和。
华为机试题 HJ33 整数与IP地址间的转换 一、题目描述 描述 原理:ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成 一个长整数...举例:一个ip地址为10.0.3.193 每段数字 相对应的二进制数 10 00001010 0...题目的主要信息: ip地址的每段可以看成是一个0-255的整数,把每段拆分成一个二进制形式组合起来,然后把这个二进制数转变成一个长整数 输入需要将一个ip地址转换为整数、将一个整数转换为ip地址 解法...1 我一开始想到的思路是针对10.0.3.193这种点分十进制的IP地址,将其转换成字符串,然后按照字符.进行分割,放入数组中,然后对数组中的4个数字进行位运算,最后进行组合。...得到了四个整数,我们可以将第0个整数左移24位,使其成为32位二进制的头8个, 然后第1个整数左移16位,第2个整数左移8位,最后一个不变,四个数通过位或操作即可组装在一起。
有一种非常巧妙的办法,先把字段分别赋值为1、2、4、8,如下: enum Permission{ Read = 1, Write = 2, Create = 4, Delete...1,其余是0,1的二进制是0001,2的二进制是0010,4的二进制是0100,8的二进制是1000,我们可以通过二进制某一位上是否有1来表示是否有这个权限,比如0001第四位上是1表示有读的权限,再比如...:0011可以表示有读和写的权限,所以我们可以通过这些基本权限来组合新的权限 1.如何组合新的权限 比如说我们要组合读和写的权限,可以这样: enum Permission{ Read = 1...位运算: 指的是两个数字转换成二进制后用每一位进行的运算,位运算有很多种,|:或运算是其中之一 首先分别拿到读和写的二进制:0001,0010,它俩进行或运算,或运算的规则是用每一位进行比较,有一位是...我们再来看这段代码(target & p) === p,其中&叫做且运算,它也是位运算中一种 且运算:比较两个数的二进制,只要当两个数的二进制相同位置上都是1的时候才是1,反之为0。
那么有没有什么解决方案呢?...方案二: 这就是本文的重点了,也就是我们使用“特殊标识位”的方式来实现,具体思路如下: 我们不再直接使用十进制数字来标识存储优惠信息,而是存储一个二进制数转化后的十进制数,这些1、2、3之类的优惠数字表示占二进制数的第几位...,则使用二进制数 00000001 标识,若使用了平台积分,则使用二进制数 00000010 标识,存储到DB时,转换成对应十进制数分别对应1、2;若同时使用了账户余额、平台积分,则使用二进制数 00000011...SetDiscountValue方法的实现:通过位运算来实现,(1 的方法来找到其在二进制中的位置,然后通过与value位或的方法设定所占二进制位数,最终返回设置占位后的十进制数...IsUseDiscount方法的实现:(1的方法来找到其在二进制中的位置,然后通过与value位与的方法来判断优惠项应占位是否有占位,返回判断结果。
你学计算机的,想个办法啊!” 张大胖说:“这样吧,我们搞一个错误检测的办法,以后每次我给你发送一个消息的时候,都附加上一个校验和(checksum),比如我想给你发4个数字 4 5 7 9 。”...张大胖叹了口气:“唉,看来这个求和算法太简单了,我得找到一个算法,得产生足够的混乱性和随机性才行。” 3 又是一个周末,两人见了面,互诉相思之苦以后,张大胖说:“我已经找到办法了,用除法。”...“就是把要发送的消息转换成一个巨大的二进制数,然后用咱们俩协商好的二进制数字去除,并从中得到余数。把这个余数当成校验和,与消息一并发送。你收到以后也用同样的除法除一下,验证校验和就行了。”...张二妮问道:“我对二进制加法略知一二,这除法怎么弄啊?!” 张大胖说:“很简单,和10进制除法是一样的,只不过出现借位的时候,借1不当作十,当作2就可以了。” ?...这样,checksum就是那个余数 100 ,发出去的消息就是 1001100 100。 张二妮用同样的除法一计算,核对一下余数是不是相等,就知道数据有没有错误了。
本来32个比特我们可以表示40亿个不同的数,但是在BCD编码下,只能表示1亿个数。 第二,这样的表示方式没办法同时表示很大的数字和很小的数字。...这是因为,浮点数没有办法精确表示0.3、0.6和0.9。 浮点数的二进制转化 我们输入一个任意的十进制浮点数,背后都会对应一个二进制表示。...Execute(执行指令),也就是实际运行对应的R、I、J这些特定的指令,进行算术逻辑操作、数据传输或者直接的地址跳转。...这样的电路,我们称之为组合逻辑电路(Combinational Logic Circuit)。...通过时序电路实现的触发器,能把计算结果存储在特定的电路里面,而不是像组合逻辑电路那样,一旦输入有任何改变,对应的输出也会改变。 时序电路使得不同的事件按照时间顺序发生。
一般一个int整形是4个字节,也就是32位bit,我们通过这32位bit上0和1的组合可以表示多大21亿个不同的数。...数字和状态是一一对应的,因为每个整数转化成二进制都是唯一的。 也就是说一个整数可以转化成二进制数,它可以代表某个集合的一个状态,这两者一一对应。这一点非常重要,是后面一切推导的基础。...如果我们想出了解二元一次方程的办法,那么必然也可以用来解一元一次方程,因为我们只需要令另一个未知数等于0就是一元一次方程了。...下图是一个逻辑电路,假设我们知道它的输出是True,我们也知道了电路的结构,那么请问我们能否确定一定可以找到一个输入的组合,使得最后的输出是True吗?...这样的问题是我们没有办法再回到0了,因为一个点只能走一次,所以最后的时候需要再寻找回到0点的最优路径。 (1 的值是从0到n-1个二进制位都是1的值,表示这n个位置全部已经遍历过了。
可以看出来,无论要哈希的文本有多长、多短,通过 MD5 哈希之后,得到的哈希值的长度都是相同的,而且得到的哈希值看起来像一堆随机数,完全没有规律。...实际上,不管是什么哈希算法,我们只能尽量减少碰撞冲突的概率,理论上是没办法做到完全不冲突的。为什么这么说呢? 这里就基于组合数学中一个非常基础的理论,鸽巢原理(也叫抽屉原理)。...我们知道,任何文件在计算中都可以表示成二进制码串,所以,比较笨的办法就是,拿要查找的图片的二进制码串与图库中所有图片的二进制码串一一比对。如果相同,则说明图片在图库中存在。...但是,每个图片小则几十 KB、大则几 MB,转化成二进制是一个非常长的串,比对起来非常耗时。有没有比较快的方法呢? 我们可以给每一个图片取一个唯一标识,或者说信息摘要。...针对字典攻击,我们可以引入一个盐(salt),跟用户的密码组合在一起,增加密码的复杂度。我们拿组合之后的字符串来做哈希算法加密,将它存储到数据库中,进一步增加破解的难度。
. & 一个数 & 1的结果就是取二进制的最末位。...=0); } 2. | or运算通常用于二进制特定位上的无条件赋值,例如一个数or 1的结果就是把二进制最末位强行变成1。...return (a | 1) } /** * 偶数 * / public int convertToEven(int a){ return (a | 1) - 1 } 3. ^ xor运算通常用于对二进制的特定一位进行取反操作...使用not运算时要格外小心,你需要注意整数类型有没有符号。...可以看出,a shl b的值实际上就是a乘以2的b次方,因为在二进制数后添一个0就相当于该数乘以2 6. » 和shl相似,a shr b表示二进制右移b位(去掉末b位),相当于a除以2的b次方(
难度 Medium 描述 给定一个int类型的候选集,和一个int类型的target,要求返回所有的数字组合,使得组合内所有数字的和刚好等于target。...这个原理非常简单,我们都知道在计算机二进制当中每一个二进制位只有两个状态0或者1,那么我们就用1表示拿,0表示不拿,那么这三个数拿或者不拿的状态其实就对应一个二进制的数字了。...我们拿到了之后,只需要将它和状态state做一个二进制中的与运算,就可以得到state中第i位究竟是0还是1了。 因为在二进制当中,and运算会将两个数的每一位做与运算,运算的结果也是一个二进制数。...当然不会白写,针对这种情况也有办法。其实很简单,因为题目当中规定所有的元素都是正数,那么对于每一个元素而言,我们最多取的数量是有限的。...原因也很简单,因为前面递归的过程当中已经选过pos和pos+1的组合了,我们如果选了pos和pos+3的组合一定会构成重复。
领取专属 10元无门槛券
手把手带您无忧上云