题目:两整数相除

难度:Medium

题目内容

Given two integers dividend and divisor, divide two integers without using multiplication, division and mod operator.

Return the quotient after dividing dividend by divisor.

The integer division should truncate toward zero.

翻译

给定两个整数,被除数和除数,不使用乘法,除法和mod运算符。

在除以除数后,返回商数。

整数除法应该截断为零。

Example 1:

Input: dividend = 10, divisor = 3
Output: 3

Example 2:

Input: dividend = 7, divisor = -3
Output: -2

我的思路:因为此题需要考虑的边界情况太多,而重点考察的却不是这些,故只做算法分析,不求跑通所有代码。

    最笨的方法:直接循环减去除数。。。

    方法二:之前印象中好像在哪见过,每次循环都减去能减的最大的除数*2^n,并且每次循环把2次幂都加起来。商就是这些2次幂的和。

举个例子:20/3,

  第一次循环,20>3*1,20>3*2,20>3*2*2,已经最大,打住, dividend=20-3*2*2=8, ans = 2*2 = 4

  第二次循环,8>3*1,8>3*2,已经最大,打住, dividend=8-3*2=2, ans = 4 + 2 = 6

  dividend < 3 退出循环,最后 ans = 6

MyCode

     public int divide(int dividend, int divisor) {
if (dividend != 0 && dividend == -dividend && divisor == -1) {
return -(dividend+1);
}
return div(dividend, divisor);
}
public static int div(int x, int y) {
int tag = 1;
if ((x ^ y) < 0) { // 位运算符优先级很低,记得加括号
tag = -1;
if (x < 0) {
x = -x;
} else {
y = -y;
}
} else if (x < 0) {
x = -x;
y = -y;
} // 都设置成正整数
int ans = 0;
while (x >= y) {
int flag = 1;
while ((x >> 1) >= y * flag) { // 如果使用x >= y * (flag << 1) 则有可能溢出
flag <<= 1;
}
x -= y*flag;
ans += flag;
}
return ans*tag;
}

编码过程中出现问题

1、bad operand types for binary operator “^”

  ————位运算符的优先级很低,甚至比==都要低,所以遇见位运算符要记得加括号。

2、溢出

  ————在23行处,进行了>>1(乘以2)的判断运算,此时可能溢出,所以在进行判断运算时,即先运算再判断是否能如此运算的时候,应该将判断符(==、>=等)两边的运算符平衡一下,如果一边可能溢出,则将此运算符移至另一边。【此处与之前的leetCode的某一题貌似是 数字反转 很像】

答案代码

    public int divide(int dividend, int divisor) {
if(dividend<<1 == 0 && divisor == -1){// x /y = -2^32 / -1, overflow
return (-1) >>> 1;
} if(divisor == 1 || dividend == 0){ // x / y = x / 1 or 0 / y
return dividend;
}
if(divisor == dividend) return 1; // x / y when x == y
else if(divisor<<1 == 0) return 0; // x / y = x / (-2^32) int sign; //sign
if(divisor < 0 && dividend < 0 || divisor > 0 && dividend > 0){
sign = 1;
}else{
sign = -1;
} divisor = divisor < 0 ? -divisor : divisor; // positive divisor
int left = dividend, res = 0;
if(dividend << 1 == 0){ // if x / y = (-2^32) / y, first we add x by y, then -x will not overflow
left += divisor;
res++;
}
left = left > 0 ? left : -left; int tDivisor = divisor, tA = 1;
while(left >= divisor){
tDivisor = divisor;
tA = 1;
while(tDivisor << 1 > 0 && left >= tDivisor << 1){ // max tDivisor = tA * divisor <= left
tDivisor <<= 1;
tA <<= 1;
}
res += tA;
left -= tDivisor;
}
return sign == 1 ? res : -res;
}

其实真正的代码从27行开始,和我代码是一个意思,不过前面多出了很多处理边界的情况,在此不做讨论。

另外一种方法——二分法

和朋友讨论发现另外一种巧妙地解法,用二分法:

     public static int div2(int x, int y) {
int tag = 1;
if ((x ^ y) < 0) { // 位运算符优先级很低,记得加括号
tag = -1;
if (x < 0) {
x = -x;
} else {
y = -y;
}
} else if (x < 0) {
x = -x;
y = -y;
}
int ans = 0; // 算法从此处开始
int low = 1;
int high = x;
while (low <= high) {
int mid = low + ((high-low)>>1);
int rest = x - y*mid;
System.out.println(rest);
if (rest >= 0 && rest < y) {
ans = mid;
break;
}
if (rest < 0) {
high = mid - 1;
} else if (rest >= y) {
low = mid + 1;
}
}
return ans * tag;
}

LeetCode第[29]题(Java):Divide Two Integers的更多相关文章

  1. 【LeetCode每天一题】Divide Two Integers(两整数相除)

    Given two integers dividend and divisor, divide two integers without using multiplication, division ...

  2. LeetCode第[18]题(Java):4Sum 标签:Array

    题目难度:Medium 题目: Given an array S of n integers, are there elements a, b, c, and d in S such that a + ...

  3. LeetCode第[1]题(Java):Two Sum 标签:Array

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  4. LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2

    题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...

  5. LeetCode第[1]题(Java):Two Sum (俩数和为目标数的下标)——EASY

    题目: Given an array of integers, return indices of the two numbers such that they add up to a specifi ...

  6. 【Leetcode】【Medium】Divide Two Integers

    Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...

  7. leetcode-【中等题】Divide Two Integers

    题目 Divide two integers without using multiplication, division and mod operator. If it is overflow, r ...

  8. LeetCode第[4]题(Java):Median of Two Sorted Arrays 标签:Array

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

  9. LeetCode第[4]题(Java):Median of Two Sorted Arrays (俩已排序数组求中位数)——HARD

    题目难度:hard There are two sorted arrays nums1 and nums2 of size m and n respectively. Find the median ...

随机推荐

  1. 记录--常用的linux命令

    mysql event /*查询event是否开启(查询结果Off为关闭 On为开启)*/ show variables like '%sche%'; /*开启/关闭命令(1开启--0关闭)*/ se ...

  2. 并发编程5 操作系统&进程

    一.今日大纲 1.multiprocessing模块简单应用 2.for循环创建进程 3.进程传参方式和创建方式2 4.join方法 5.操作系统基础 二.今日内容 (1)操作系统简单介绍 多道技术: ...

  3. 支付宝SDK的使用方法

    前奏 现在随着移动开发的快速发展,越来越多的应用要求在线支付功能.最近做了一个关于支付宝支付功能的应用,在使用支付宝的过程中,遇到一些不必要的弯路,因此,写了这篇文章总结一下关于ios开发如何使用支付 ...

  4. GO语言中使用OpenCV

    GO语言中使用OpenCV - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision http://wiki.opencv.org.c ...

  5. type属性对jq-post在ie、chrome、ff的兼容

    w http://stackoverflow.com/questions/8834635/post-not-working-in-firefox

  6. Java程序员面试题集(1-50

    下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最 ...

  7. Java 之单例设计模式

    设计模式: 对问题行之有效的解决方式, 其实它是一种思想. 单例设计模式 解决的问题:就是可以保证一个类在内存中的对象唯一性. 即单个实例. 比如对于A 和 B 两个程序使用同一个配置信息对象时, A ...

  8. Java 集合框架查阅技巧

    如何记录每一个容器的结构和所属体系呢? List ArrayList LinkedList Set HashSet TreeSet 其中,后缀名就是该集合所属的体系,前缀名就是该集合的数据结构. 看到 ...

  9. python可变参数*args, **kwargs

    python可变参数*args, **kwargs def foo(* args, ** kwargs): print ' args = ',  args print ' kwargs = ',  k ...

  10. 洛谷 P2233 [HNOI]公交车线路

    洛谷 不知道大家做没做过传球游戏,这一题和传球游戏的转移方程几乎一样. 令\(A\)为\(1\)点,\(E\)为\(5\)点,那么\(f[i][j]\)代表第i步走到j的方案数. \[f[i][j]= ...