两数相除

给你两个整数,被除数 dividend 和除数 divisor。将两数相除,要求 不使用 乘法、除法和取余运算。 整数除法应该向零截断,也就是截去(truncate)其小数部分。例如,8.345 将被截断为 8 ,-2.7335 将被截断至 -2 。 返回被除数 dividend 除以除数 divisor 得到的 商 。 注意:假设我们的环境只能存储 32 位 有符号整数,其数值范围是 [−231, 231 − 1] 。本题中,如果商 严格大于 231 − 1 ,则返回 231 − 1 ;如果商 严格小于 -231 ,则返回 -231 。

看到题第一反应:这啥鬼,除法不是很简单,为啥要搞这么复杂 看了题解:牛,有点东西,思路很好很清奇

1.边界判断 此处假设除数不为0 被除数为0,结果必然为0 除数为1,结果为被除数 除数为-1时,一般情况只取反被除数就可以,但注意题目要求32位,范围是-2^31 ~ 2^31-1,假设被除数恰好是-2^31,那么取反后越界了,超过2^31-1,因此返回INT32_MAX

2.开始运算 方便期间,先标记结果的正负,然后吧所有数据转成正数处理,最后结果用标记处理正确即可 「快速乘」算法实现,类似快速幂算法,也是本体的核心,具体实现见代码

方法一、类二分查找

Swift

func divide(_ dividend: Int, _ divisor: Int) -> Int {

//被除数为0

if dividend == 0 {

return 0

}

//除数为1

if divisor == 1 {

return dividend

}

if divisor == -1 {

// 如果被除数比最小值还小,除以-1之后,就会比边界值还大,所以此时返回最大边界值,其他情况,返回相反数

if dividend > Int(Int32.min) {

return -dividend

}

return Int(Int32.max)

}

// 结果是否为正数

let sign = dividend > 0 && divisor > 0 || dividend < 0 && divisor < 0

let a = dividend > 0 ? dividend : -dividend

let b = divisor > 0 ? divisor : -divisor

let res = div(a, b)

return sign ? res : -res

}

func div(_ a: Int, _ b: Int) -> Int {

if a < b {

return 0

}

var count = 1

var result = b

while result + result <= a {

count += count

result += result

}

return count + div(a-result, b)

}

OC

-(int32_t)divide:(int32_t)dividend divisor:(int32_t)divisor {

if (dividend == 0) {

return 0;

}

if (divisor == 1) {

return dividend;

}

if (divisor == -1) {

if (dividend > INT32_MIN) {

return -dividend;

}

return INT32_MAX;

}

//结果正负标记

bool isPositive = (dividend > 0 && divisor > 0) || ( dividend < 0 && divisor < 0);

int32_t a = dividend > 0 ? dividend : -dividend;

int32_t b = divisor > 0 ? divisor : -divisor;

int32_t res = [self divide:a divisor:b];

return isPositive ? res : -res;

}

//「快速乘」算法

- (int32_t)divWithA:(int32_t)a b:(int32_t)b {

if (a < b) {

return 0;

}

int32_t count = 1;

int32_t result = b;

while (result + result <= a) {

count += count;

result += result;

}

return count + [self divWithA:a-result b:b];

}

精彩链接

评论可见,请评论后查看内容,谢谢!!!评论后请刷新页面。