当前位置: 首页 > Web前端 > JavaScript

【算法】整数

时间:2023-03-27 00:45:08 JavaScript

面试题1:整数除法题:输入2个int型整数,除法返回商,不要使用乘号'*'、除号'/'和余数'%''。当发生溢出时,返回最大的整数值。假设除数不为0,比如输入15和2,输出15/2,即7。减法实现除法和减法2/***@param{number}a*@param{number}b*@return{number}*/vardivide=function(a,b){if(a==-2147483648&&b===-1)return2**31-1letres=0letnagative=2if(a>0){a=-anagative-=1}if(b>0){b=-bnagative-=1}letval=awhile(val<=b){val-=bres++}returnnagative==1?-res:res};时间复杂度O(n)/***@param{number}a*@param{number}b*@return{number}*/vardivide=function(a,b){if(a==-2147483648&&b===-1)return2**31-1letnagative=2if(a>0){a=-anagative-=1}if(b>0){b=-bnagative-=1}constres=dividecore(a,b)返回nagative==1?-res:res};vardividecore=function(a,b){letresult=0while(a<=b){letvalue=bletquotient=1while(a<=value<<0){quotient+=quotientvalue+=value}result+=quotienta-=value}returnresult}使用位运算本质上就是减法/***@param{number}a*@param{number}b*@return{number}*/vardivide=function(a,b){constMAX=Math.pow(2,31)-1,MIN=-Math.pow(2,31)if(a==MIN&&b==-1)返回MAXif(a==MIN&&b==1)returnMINconstsign=(a>0)^(b>0)a=Math.abs(a),b=Math.abs(b)让n=0for(leti=31;i>=0;i--){if(a>>>i>=b){a-=b<0){nagative-=1}if(b>0){nagative-=1}如果nagative为1,则为负orthen使用异或判断//1^1=0,0^0=0,1^0=1constsign=(a>0)^(b>0))sign=(a>0)^(b>0),当它是为1时表示为负数,为0时表示为正数。二进制整数在计算机中以二进制形式表示。例如,十进制的2二进制为10,十进制的10二进制为1010。面试题2:二进制加法给定两个01字符串a和b,请计算它们的和并将其作为二进制字符串输出。输入是一个非空字符串,只包含数字1和0。基数转换先将aa和bb转换成十进制数,然后求和后转换成二进制数。类解决方案{publicStringaddBinary(Stringa,Stringb){returnInteger.toBinaryString(Integer.parseInt(a,2)+Integer.parseInt(b,2));}}作者:LeetCode-Solution链接:https://leetcode-cn.com/problems/JFETK5/solution/er-jin-zhi-jia-fa-by-leetcode-solution-fa6t/来源:LeetCode版权所有给作者。商业转载请联系作者授权,非商业转载请注明出处。模拟二元运算/***@param{string}a*@param{string}b*@return{string}*/varaddBinary=function(a,b){letal=a.length-1letbl=b.length-1letres=[]lete=0;while(al>=0||bl>=0){constc=a.charAt(al)||0常量d=b.charAt(bl)||0if(parseInt(c)+parseInt(d)+e>2){res.unshift(1)e=1}elseif(parseInt(c)+parseInt(d)+e>1){res.unshift(0)e=1}else{res.unshift(parseInt(c)+parseInt(d)+e)e=0}al--bl--}//防止剩余进位if(e!==0){res.unshift(e)}returnres.join('')};别人的代码简化了中间判断varaddStrings=function(num1,num2){letres=''leti1=num1.length-1leti2=num2.length-1letcarry=0while(i1>=0||i2>=0){constx=i1>=0?num1[i1]-'0':0consty=i2>=0?num2[i2]-'0':0constsum=x+y+carryres+=(sum%2)carry=Math.floor(sum/2)i1--i2--}if(carry)res+=carryreturnres.拆分(“”).reverse().join(“”)};作者:tangweiqun链接:https://leetcode-cn.com/problems/JFETK5/solution/jian-dan-yi-dong-javacpythonjs-pei-yang-r6bem/来源:LeetCode版权归作者所有。如需商业转载,请联系作者获得授权。非商业转载请注明出处。位运算需要位运算基础吗?面试题3:前n个数的二进制形式1的个数题目:输入一个非负数n,请计算0到n之间每个数的二进制形式1的个数,并输出一个数组。例如输入n为4,由于1的二进制形式0,1,2,3,4的个数分别为0,1,1,2,1,所以输出数组[0,1,1,2,1]。使用for循环统计从0到n的每个整数i的二进制形式中1的个数。于是问题转化为如何求一个整数i的二进制形式中1的个数。简单地计算每个整数的二进制形式中1的个数有许多不同的方法可以计算整数i的二进制形式中1的个数。一种比较有效的方法是每次用“i&(i-1)”把整数i最右边的1变成0。整数i减1,那么它最右边的1就变成0。如果有0到在它的右边,右边所有的0都变成1,而左边的所有位保持不变。下面对i和i-1进行位与运算,相当于把最右边的1变成0。以二进制1100为例,减1的结果为1011。位与运算的结果1100和1011正好是1000,二进制1100最右边的1变成0,结果正好是1000。/***@param{number}n*@return{number[]}*/varcountBits=function(n){letres=[]for(leti=0;i<=n;i++){letj=i让m=0while(j!=0){j=j&(j-1)m++}res[i]=m}returnres};如果一个整数总共有k位,那么它的二进制形式可能有O(k)个1。上述代码中,while循环中的代码对于每个整数都会执行O(k)次,因此,上述代码的时间复杂度为O(nk)。优化/***@param{number}n*@return{number[]}*/varcountBits=function(n){letres=newArray(n+1).fill(0)for(leti=1;i<=n;i++){res[i]=res[i&(i-1)]+1}returnres};时间长了,没看懂。。。根据“i/2”二进制形式的1的个数计算i面试题4:只出现一次的数给你一个数组nums个整数,其中每个元素恰好出现3个次,除了某个元素只出现一次。请找到并返回只出现一次的元素。例子1:输入:nums=[2,2,3,2]输出:3第一反应是用map哈希表/***@param{number[]}nums*@return{number}*/varsingleNumber=function(nums){letmap={}for(leti=0;i