29. 两数相除
package leetcode; public class demo_29 { public int divide(int dividend, int divisor) { int flag=0; //为了防止溢出,转化为长整型 long ldividend=dividend; long ldivisor=divisor; //调整最后输出的正负号 if(dividend>0&&divisor<0) {flag=1;} if(dividend<0&&divisor>0) {flag=1;} //全部换成正数运算 if(ldividend<0) {ldividend=-ldividend;} long d=ldividend; if(ldivisor<0) {ldivisor=-ldivisor;} //被除数小于除数,结果为0 if(ldividend<ldivisor) {return 0;} long div=1; long mul=ldivisor; //估算被除数需要除以2的个数 while(d>=ldivisor) { d=d>>1; //找出可能的商 div=div<<1; //找出最接近被除数的数 mul=mul<<1; } //因为多乘了一次2,所以除以2 mul=mul>>1; div=div>>1; //从最接近开始找 while(mul<=ldividend) { mul=mul+ldivisor; div=div+1; } div=div-1; //判断是否溢出 if(flag==0&&div>2147483647) {return 2147483647;} if(flag==1) { System.out.println(-div); return (int)-div; } else { System.out.println(div); return (int)div; } } public static void main(String[] args) { // TODO Auto-generated method stub demo_29 d29=new demo_29(); d29.divide(2, 2); } }
简化算法
public int divide(int dividend, int divisor) { int flag=0; //为了防止溢出,转化为长整型 long ldividend=dividend; long ldivisor=divisor; //调整最后输出的正负号 if(dividend>0&&divisor<0) {flag=1;} if(dividend<0&&divisor>0) {flag=1;} //全部换成正数运算 if(ldividend<0) {ldividend=-ldividend;} if(ldivisor<0) {ldivisor=-ldivisor;} //被除数小于除数,结果为0 if(ldividend<ldivisor) {return 0;} long div; div=div(ldividend, ldivisor); //判断是否溢出 if(flag==0&&div>2147483647) {return 2147483647;} if(flag==1) { return (int)-div; } else { return (int)div; } }
//递归寻找可能的商 long div(long a, long b){ // 似乎精髓和难点就在于下面这几句 if(a<b) return 0; long count = 1; long tb = b; // 在后面的代码中不更新b while((tb+tb)<=a){ count = count + count; // 最小解翻倍 tb = tb+tb; // 当前测试的值也翻倍 } return (count + div(a-tb,b)); }
浙公网安备 33010602011771号