第一章 大数问题
刷题第一站
29. 两数相除
由于整数会有越界,因此用负数保存下一切。这个是可以得到正确结果的!
但是由于这里是一个一个减的,超时了。
class Solution {public int divide(int dividend, int divisor) {int flag = (dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0) ? -1 : 1;if (dividend > 0) dividend = -dividend;if (divisor > 0) divisor = -divisor;int res = 0;while (dividend <= divisor) {res -= 1;dividend -= divisor;}if (flag < 0) {return res;} else {if (res == Integer.MIN_VALUE) {return Integer.MAX_VALUE;}return -res;}}}
现在用二分法和快速乘法解决!
class Solution {public static int divide(int dividend, int divisor) {long result = 0;long x = dividend;long y = divisor;boolean negative = (x < 0 && y > 0) || (x > 0 && y < 0);if (x < 0) {x = -x;}if (y < 0) {y = -y;}// 由于x/y的结果肯定在[0,x]范围内,所以对x使用二分法long left = 0;long right = x;while (left < right) {long mid = left + right + 1 >> 1; // 为什么呢?看答案if (quickMulti(mid, y) <= x) {// 相乘结果不大于x,左指针右移left = mid;} else {right = mid - 1;}}result = negative ? -left : left;// 判断是否溢出if (result < Integer.MIN_VALUE || result > Integer.MAX_VALUE) {return Integer.MAX_VALUE;}return (int)result;}/*** 快速乘法** @param a 乘数* @param b 被乘数* @return 积*/public static long quickMulti(long a, long b) {long result = 0;while (b > 0) {if ((b & 1) == 1) {// 当前最低位为1,结果里加上aresult += a;}// 被乘数右移1位,相当于除以2b >>= 1;// 乘数倍增,相当于乘以2a += a;}return result;}}

