一、题目1
二、思路
思路一:
暴力循环,判断当前剩余的部分能不能进行减一操作(假定是两个正数相除),能就继续,不能就结束并返回结果。
难点在于对什么时候停止循环进行判断,因为有符号不同这种情况。
最后我的解决办法就是依旧判断是否的大于(假定正数除以负数),这样就多循环了两次,最后在结果中减去就ok了,然后最后提交超时,据我判断是倒在了-231这个边界值上面了,可以输出结果,但是,超时。
思路二:
这个思路主要的依据就是对任何一个整数n有:n=2n×a+2n-1×a+……+21×a+20×a
然后就通过移位运算,最后得到结果。
补充:
对于符号的解决方法:我下面的代码中思路一是根据不同的符号进行判断,然后进行相应的方法。
思路二的办法是将其均转化为正数进行计算。
然后提交看了大佬的代码之后发现,转化为负数计算更加的方便,因为正数转负数不会越界,负数转正数存在越界的情况。
三、代码
public class T0029 {
public T0029() {
System.out.println( divide( -2147483647, 2 ) +" \t" + (-2147483647/2));
System.out.println( divide( -2147483647, -2 ) +" \t" + (-2147483647/-2));
System.out.println( divide( 2147483647, 2 ) +" \t" + (2147483647/2));
System.out.println( divide( 2147483647, 1 ) +" \t" + (2147483647/1));
System.out.println( divide( -2147483648, 1 ) +" \t" + (-2147483648/1));
System.out.println( divide( 2147483647, -1 ) +" \t" + (2147483647/-1));
System.out.println( divide( -2147483648, -1 ) +" \t" + (-2147483648/-1));
for ( int i = 0; i < 10; i++ ){
int a = (int)(Math.random()*1000);
int b = (int)(Math.random()*100);
System.out.println( divide( a, b ) == (a/b) );
}
for ( int i = 0; i < 10; i++ ){
int a = (int)(Math.random()*1000);
int b = (int)(Math.random()*100);
System.out.println( divide( -a, b ) == (-a/b) );
}
for ( int i = 0; i < 10; i++ ){
int a = (int)(Math.random()*1000);
int b = (int)(Math.random()*100);
System.out.println( divide( a, -b ) == (a/-b) );
}
for ( int i = 0; i < 10; i++ ){
int a = (int)(Math.random()*1000);
int b = (int)(Math.random()*100);
System.out.println( divide( -a, -b ) == (-a/-b) );
}
}
public int divide(int dividend, int divisor) {
//判断是否是被除数为0,被除数除数均为最小值,除数为最小值
//并对相应的情况进行处理
if ( dividend == 0 || divisor==Integer.MIN_VALUE){
return dividend==Integer.MIN_VALUE?1:0;
}
int a = 0; //被除数的绝对值
int b = Math.abs(divisor); //除数的绝对值
boolean special = false; //被除数是否是最小值
int result = 0; //商
int tmp = b; //暂时存储移位的结果
int stape = 1; //暂时存储当前移位的值
//判断被除数是否是最小值,并取其绝对值
if ( dividend != Integer.MIN_VALUE ){
a = Math.abs(dividend);
}else {
a = Math.abs(dividend+1);
special = true;
}
//当被除数小于除数时循环结束
while ( a >= b ){
//判断此次位移结果是否会越界
//不越界就进行位移,可能会越界就进行加减和初始化操作
if ( tmp < Integer.MAX_VALUE >> 2 ){
//当位移结果小于被除数时,继续进行位移操作
//当大于时,就用被除数减去位移结果,并将stape的值加在result上
//同时将结果tmp、stape再次初始化
if ( tmp<<2 < a ){
tmp = tmp<<2;
stape = stape<<2;
}else {
a = a - tmp;
tmp = b;
result +=stape;
stape = 1;
}
}else{
a = a - tmp;
tmp = b;
result +=stape;
stape = 1;
}
}
//将result的符号修正
if ( (dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0))
result = -result;
//若被除数是最小值,将上面减去的1重新加回来,并进行计算
if ( special && a+1==b ){
//判断计算结果是否会越界
if (result== Integer.MAX_VALUE)
return Integer.MAX_VALUE;
else
result = result-1;
}
return result;
}
public int divide1(int dividend, int divisor) {
if ( dividend == 0 ){
return 0;
}
int result = 0;
int tmp = divisor;
int stape = 1;
if ( dividend>0&&divisor>0 ){
while ( dividend >= divisor ){
if ( tmp < Integer.MAX_VALUE >> 2 ){
if ( tmp<<2 < dividend ){
tmp = tmp<<2;
stape = stape<<2;
}else {
dividend = dividend - tmp;
tmp = divisor;
result +=stape;
stape = 1;
}
}else{
dividend = dividend - tmp;
tmp = divisor;
result +=stape;
stape = 1;
}
}
}else if ( dividend>0&&divisor<0 ){
while ( dividend >= divisor ){
if ( tmp < Integer.MIN_VALUE >> 2 ){
if ( tmp<<2 < dividend ){
tmp = tmp<<2;
stape = stape<<2;
}else {
dividend = dividend + tmp;
tmp = divisor;
result -=stape;
stape = 1;
}
}else{
dividend = dividend + tmp;
tmp = divisor;
result -=stape;
stape = 1;
}
}
result += 2;
}else if ( dividend<0&&divisor>0 ){
while ( dividend <= divisor ){
if ( tmp < Integer.MIN_VALUE >> 2 ){
if ( tmp<<2 < dividend ){
tmp = tmp<<2;
stape = stape<<2;
}else {
dividend = dividend + tmp;
tmp = divisor;
result -=stape;
stape = 1;
}
}else{
dividend = dividend + tmp;
tmp = divisor;
result -=stape;
stape = 1;
}
}
result += 2;
}else {
while ( dividend <= divisor ){
if ( result == Integer.MAX_VALUE )
return Integer.MAX_VALUE;
if ( tmp < Integer.MIN_VALUE >> 2 ){
if ( tmp<<2 < dividend ){
tmp = tmp<<2;
stape = stape<<2;
}else {
dividend = dividend - tmp;
tmp = divisor;
result +=stape;
stape = 1;
}
}else{
dividend = dividend - tmp;
tmp = divisor;
result +=stape;
stape = 1;
}
}
}
return result;
}
public static void main(String[] args) {
T0029 t0029 = new T0029();
}
}
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/divide-two-integers
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。 ↩︎