zoukankan      html  css  js  c++  java
  • LeetCode 28 Divide Two Integers

    Divide two integers without using multiplication, division and mod operator.

    思路:1.先将被除数和除数转化为long的非负数,注意一定要为long。由于Integer.MIN_VALUE的绝对值超出了Integer的范围。

              2.常理:不论什么正整数num都能够表示为num=2^a+2^b+2^c+...+2^n。故能够採用2^a+2^b+2^c+...+2^n来表示商,即dividend=divisor*(2^a+2^b+2^c+...+2^n),(a,b,c,....m互不相等。且最大为31,最小为0)

    而商的最大值为Integer.MIN_VALUE的绝对值。商最多有32个2的指数次相加。故时间复杂度为常数。

              3.divisor*2^a用计算机表示为divisor<<a;

              注意:若每次仅仅加一个divisor。则面对Integer.MAX_VALUE除以一个非常小的常数(eg:1。2。3),会超时。

    public class Solution {
    	public int divide(int dividend, int divisor) {
    
    		boolean positive = true;
    		if((dividend>0&&divisor<0)||(dividend<0&&divisor>0))
    			positive = false;
    		long did=dividend>=0?(long)dividend:-(long)dividend;
    		long dis=divisor>=0?(long)divisor:-(long)divisor;
    
    		long quotients = positiveDivide(did, dis);
    		if (!positive)
    			return (int)-quotients;
    		return (int)quotients;
    	}
    
    	public long positiveDivide(long did, long dis) {
    		long[] array = new long[32];
    		long sum = 0;
    		int i = 1;
    		long quotients = 0;
    		if(dis==1) return did;//为了避免-did=Integer.MIN_VALUE,而dis=1。出现故障
    		for (array[0]=dis; i < 32 && array[i - 1] <= did; i++) 
    			array[i] = array[i - 1] << 1;
    		
    		for (i = i - 2; i >= 0; i--) {
    			if (sum <= did - array[i]) {
    				sum += array[i];
    				quotients += 1 << i;
    			}
    		}		
    		return quotients;
    	}
    }

    优化版,减小内存的消耗。不申请动态数组

    public class Solution {
    	public int divide(int dividend, int divisor) {
    
    		boolean positive = true;
    		if((dividend>0&&divisor<0)||(dividend<0&&divisor>0))
    			positive = false;
    		long did=dividend>=0?

    (long)dividend:-(long)dividend; long dis=divisor>=0?(long)divisor:-(long)divisor; long quotients = positiveDivide(did, dis); if (!positive) return (int)-quotients; return (int)quotients; } public long positiveDivide(long did, long dis) { long sum = 0; long quotients = 0; if(dis==1) return did;//为了避免-did=Integer.MIN_VALUE,而dis=1。出现故障 //sum从divisor*2^31的開始加起,不能加则试试加上divisor*2^30。 //若不能则试试divisor*2^29,依此类推 for (int i = 31; i >= 0; i--) { long temp=dis<<i;//该式为divisor*2^a //sum<=dividend则说明dividend大于divisor*(2^m+...+2^i),m最大为31 if (sum <= did - temp) { sum += temp; quotients += 1 << i;//2^i } } return quotients; } }



  • 相关阅读:
    接口框架项目示例
    接口框架开发流程总结
    requests库的简单使用
    使用flask创建简单的接口
    session和token
    解决log函数生成重复log的问题
    自定义封装logging参考
    织梦dedecms做的网站首页标题篡改跳转赌博网站解决方案
    织梦网站安全查杀
    织梦重置密码的方法和织梦网站后台登陆账号修改方法
  • 原文地址:https://www.cnblogs.com/jzssuanfa/p/6877700.html
Copyright © 2011-2022 走看看