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 ...
随机推荐
- python macos scrapy ,gevent module
easy_install pip pip install scrapy pip install ipython ImportError: No module named items https://g ...
- Java中native关键字使用
native是与C++异构开发的时候用的.java自己开发不会使用
- Java 语言基础之数组(一)
数组定义及格式: 数组: 同一种类型数据的集合, 就是一个容器 定义数组格式1: 元素类型[] 数组名 = new 元素类型[元素个数(即数组长度)]; 说明: 数组是一个容器.而容器属于一个实体,实 ...
- tpot蜜罐平台搭建
iso安装:https://github.com/dtag-dev-sec/tpotce autoinstaller安装:https://github.com/dtag-dev-sec/tpotce ...
- 流畅的python 使用一等函数实现设计模式
案例分析:重构“策略”模式 经典的“策略”模式 电商领域有个功能明显可以使用“策略”模式,即根据客户的属性或订单中的商品计算折扣.假如一个网店制定了下述折扣规则. 有 1000 或以上积分的顾客,每个 ...
- 我的Android进阶之旅------>Java全角半角的转换方法
一中文全角和半角输入的区别 1全角指一个字符占用两个标准字符位置 2半角指一字符占用一个标准的字符位置 3全角与半角各在什么情况下使用 4全角和半角的区别 5关于全角和半角 6全角与半角比较 二转半角 ...
- 什么是EJB
学习EJB可以加深对J2EE平台的认识. 百科定义EJB: 被称为java企业bean,服务器端组件,核心应用是部署分布式应用程序.用它部署的系统不限定平台.实际上ejb是一种产品,描述了应用组件要解 ...
- django重写用户模型
重写一个UserProfile继承自带的AbstractUser # -*- coding: utf-8 -*- from __future__ import unicode_literals fro ...
- PHP函数的创建
看代码 PHP函数的创建,包括参数,和其他的语言一样 <?php #PHP crate function function writeName($name) { echo 'Name is '. ...
- C#:当前时间转换成文件名
DateTime.Now.ToFileTime().ToString(); 结果是一个字符串,类似:131238643554094913.