Leetcode笔记(7)Divide Two Integers

Divide two integers without using multiplication, division and mod operator.

又是一道乍看很简单的题目。多年来的考试经验表明:题目越是简单的,解题步骤反而越是纠结。这就是一道典型的例子。

首先第一步要确认思路。乘除取模不能用,剩下+-和其他运算符。不能用乘号,可以用加号来乘二,加到刚好小于被除数为止。然后减掉做下一轮。

然后想起,乘二这个运算,位移更擅长,对于int而言,左移一位就是乘二。

这题的思路最后结果如下:

代码看上去很简单,但是实际上有很多坑,如果不是从头写下来很容易就忽略了,本文的主要目的,就是找坑排雷:

  • dividend和divisor的符号。思考算法时默认它们都是正数,实际却并非如此,各种情况都需要考虑。为了应对这一问题,可以先对绝对值求结果,然后附上符号
  • int的绝对值,int里面有一个特殊的数字:-2147483648,它的绝对值或者相反数 2147483648是超出int的范围的,对于这一情况需要特殊处理。所以不能直接调用 divide(-dividend, divisor)或者divide(dividend, – divisor)。也不能写 int dv = abs(dividend)。处理方式是使用long long来保存其绝对值
  • 计算绝对值的时候要写 long long dv = abs((long long)dividens)的原因是,abs()有两个重载版本,其中一个是abs(int),另外一个是abs(long),如果不进行显式转换,则调用abs(int),对-2147483648的返回结果仍是-2147483648
  • 计算两个整数商的时候,有两种选择:将被除数dv右移或者将除数ds右移,循环终止条件是dv < ds。以上代码选用了右移被除数dv。原因是:当dv最高位(除符号位外)为1时,左移ds可能因为小于dv而将ds的有效位从最左移出,既会使比较出错,也可能导致死循环。
  • 最后,在return res这里,还是可能会出错的,但是就不在这段程序的考虑范围了,错误输入: -2147483648, -1
  • 坑啊坑啊都是坑。long long是个好东西。

你可能感兴趣的:(Leetcode笔记(7)Divide Two Integers)