LeetCode第[29]题(Java):Divide Two Integers
题目:两整数相除
难度: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的更多相关文章
- 【LeetCode每天一题】Divide Two Integers(两整数相除)
Given two integers dividend and divisor, divide two integers without using multiplication, division ...
- 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 + ...
- 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 ...
- LeetCode第[46]题(Java):Permutations(求所有全排列) 含扩展——第[47]题Permutations 2
题目:求所有全排列 难度:Medium 题目内容: Given a collection of distinct integers, return all possible permutations. ...
- 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 ...
- 【Leetcode】【Medium】Divide Two Integers
Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...
- leetcode-【中等题】Divide Two Integers
题目 Divide two integers without using multiplication, division and mod operator. If it is overflow, r ...
- 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 ...
- 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 ...
随机推荐
- 记录--常用的linux命令
mysql event /*查询event是否开启(查询结果Off为关闭 On为开启)*/ show variables like '%sche%'; /*开启/关闭命令(1开启--0关闭)*/ se ...
- 并发编程5 操作系统&进程
一.今日大纲 1.multiprocessing模块简单应用 2.for循环创建进程 3.进程传参方式和创建方式2 4.join方法 5.操作系统基础 二.今日内容 (1)操作系统简单介绍 多道技术: ...
- 支付宝SDK的使用方法
前奏 现在随着移动开发的快速发展,越来越多的应用要求在线支付功能.最近做了一个关于支付宝支付功能的应用,在使用支付宝的过程中,遇到一些不必要的弯路,因此,写了这篇文章总结一下关于ios开发如何使用支付 ...
- GO语言中使用OpenCV
GO语言中使用OpenCV - OpenCV China :图像处理,计算机视觉库,Image Processing, Computer Vision http://wiki.opencv.org.c ...
- type属性对jq-post在ie、chrome、ff的兼容
w http://stackoverflow.com/questions/8834635/post-not-working-in-firefox
- Java程序员面试题集(1-50
下面的内容是对网上原有的Java面试题集及答案进行了全面修订之后给出的负责任的题目和答案,原来的题目中有很多重复题目和无价值的题目,还有不少的参考答案也是错误的,修改后的Java面试题集参照了JDK最 ...
- Java 之单例设计模式
设计模式: 对问题行之有效的解决方式, 其实它是一种思想. 单例设计模式 解决的问题:就是可以保证一个类在内存中的对象唯一性. 即单个实例. 比如对于A 和 B 两个程序使用同一个配置信息对象时, A ...
- Java 集合框架查阅技巧
如何记录每一个容器的结构和所属体系呢? List ArrayList LinkedList Set HashSet TreeSet 其中,后缀名就是该集合所属的体系,前缀名就是该集合的数据结构. 看到 ...
- python可变参数*args, **kwargs
python可变参数*args, **kwargs def foo(* args, ** kwargs): print ' args = ', args print ' kwargs = ', k ...
- 洛谷 P2233 [HNOI]公交车线路
洛谷 不知道大家做没做过传球游戏,这一题和传球游戏的转移方程几乎一样. 令\(A\)为\(1\)点,\(E\)为\(5\)点,那么\(f[i][j]\)代表第i步走到j的方案数. \[f[i][j]= ...