剑指offer第一题
题目:
给定两个整数 a
和 b
,求它们的除法的商 a/b
,要求不得使用乘号 '*'
、除号 '/'
以及求余符号 '%'
。
提示:
-231 <= a, b <= 231 - 1
b != 0
~这天正式开启算法刷题了。🏳️🌈
初始解法:
差点超时,利用的是一个一个减去。循环次数过多。
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
var divide = function(a, b) {
if(a===0)return 0;//被除数为0,直接返回0。
if(a===-Math.pow(2,31)&&b===-1)return Math.pow(2,31)-1
let count=0;//记录a,b的正负。如果是0或者2的话,说明结果为正
if(a<0)count++;
if(b<0)count++;
let num1=Math.abs(a)
let num2=Math.abs(b)
let sum=0;
while(num1>=num2){
sum++;
num1-=num2;
}
return count%2===0?sum:-sum;
};
优化算法思路:
从一个一个减,可以变成多个多个减
22-3 K==1
22-(3+3) k=k+k=2
22-(6+6) k=k+k=4
22-(12+12) k=k+k=8
此时的算法复杂度为以2为底的对数的平方!!!
/**
* @param {number} a
* @param {number} b
* @return {number}
*/
var divide = function (a, b) {
if (a === 0) return 0;//被除数为0,直接返回0。
if (a === -Math.pow(2, 31) && b === -1) return Math.pow(2, 31) - 1
let count = 0;//记录a,b的正负。如果是0或者2的话,说明结果为正
if (a < 0) count++;
if (b < 0) count++;
let num1 = Math.abs(a)
let num2 = Math.abs(b)
let sum = 0;//用来存放结果的!!!
while (num1 >= num2) {
let k = 1;//看能存放几次
while (num1 - (num2 + num2) >= 0) {
k += k;
num2 += num2;
}
num1 = num1 - num2;
num2 = Math.abs(b)
sum += k;//存储结果数量化
}
return count % 2 === 0 ? sum : -sum;
};
总结两点:
1.注意临界条件的判断。
2.优化算法的思路。双重循环。减少减的次数!
感受:
可优化的地方还有很多!!