zoukankan      html  css  js  c++  java
  • [LeetCode#29]Divide Two Integers

    The problem:

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

    If it is overflow, return MAX_INT.

    My analysis:

    The idea behind this problem is very veyr elegant, it involves important mainpulataion over the digits of a number, you must master it! And this kind of problem always involves a lot of conner cases, you should be very very careful!!
    The key idea:
    solution 1: We keep on substracting divisor from dividend, and we record the times of substraction. Once we reach a value less than divisor, we return the count. The time complexity of this solution is O(n). 
    solution 2: It also uses the idea of substraction. But it substracts in a more brave way.
    num = a_0 * 2^0  +  a_1 * 2^1 + a_2 * 2^2 + a_3 * 2^3 + a_4 * 2^4 + a_5 * 2^5
    Idea:
    2.1 We left shift divisor to reach the value just less(or equal than) dividend. 
    while (divisor <= (dividend >> 1)) { //note we stop value just bigger than (dividend >> 1), cause we would stract it. 
        divisor <<= 1;
        digit++;
    }
    2.2 Then we follow the below invariant.
    Iff dividend larger than divisor, it means we could substract divisor from dividend. And we should add the substracted parts into the return value: 
    if (dividend >= divisor ) {
        ret += (1 << digit); 
        dividend -= divisor;
    }
    Note: the digit here is used to record the current divisor's left shift. it represent (1>>digit) times of original divisor.
    Then we could test number less than divisor (with lower times of divisor), by decreasing digit by one and right shift divisor one digit. 
    digit--;
    divisor >>= 1;
    Note: digit is useds to record how many times the current divisor of the original divisor. And divisor is the actual number we opearte on. 
    while (digit >= 0) {
        if (dividend >= divisor ) {
            ret += (1 << digit);
            dividend -= divisor;
        }
        digit--;
        divisor >>= 1;
    }
    
    Some tricky skills: 
    1. the sign of two numbers' product or divide. 
    boolean is_neg = (dividend ^ divisor) >>> 31 == 1;
    ">>>" respresent we right shift the number 31 digits and fill those shifted digits with 0. 
    
    2. inorder to make the uniform comparsion when we shift digits. (and the sign only affects the result's sign, not the abs () part.) We need to use the abs value of dividend and divisor in computation. To get the abs value, we shoul consider following corner cases:
    2.1 divisor is 0, we return Integer.MAX_VALUE. 
    if (divisor == 0)
        return Integer.MAX_VALUE;
        
    2.2 dividend is Integer.MIN_VALUE(the abs() over it would result in overflow). we could substract it with divisor's abs value at first, thus we would not overflow.
    if (dividend == Integer.MIN_VALUE) {
        dividend += Math.abs(divisor);
        if (divisor == -1) //note this corner case.
            return Integer.MAX_VALUE;
        ret ++; //rember to record the substraction in the result. 
    }
    
    2.3 iff the divisor is Integer.MIN_VALUE. 
    2.3.1 iff the dividend is also Integer.MIN_VALUE, we should return 1;
    2.3.2 iff the dividend is a Integer larger than Integer.MIN_VALUE, we should return 0. 
    int ret = 0;
    if (dividend == Integer.MIN_VALUE) {
        dividend += Math.abs(divisor);
        if (divisor == -1)
            return Integer.MAX_VALUE;
        ret ++;
    }
    if (divisor == Integer.MIN_VALUE) {
        return ret;
    }
    Note the logic at here is very elegant. 

    The solution:

    public class Solution {
        public int divide(int dividend, int divisor) {
            if (divisor == 0)
                return Integer.MAX_VALUE;
            boolean is_neg = (dividend ^ divisor) >>> 31 == 1;
            int digit = 0;
            int ret = 0;
            if (dividend == Integer.MIN_VALUE) {
                dividend += Math.abs(divisor);
                if (divisor == -1)
                    return Integer.MAX_VALUE;
                ret ++;
            }
            if (divisor == Integer.MIN_VALUE) {
                return ret;
            }
            divisor = Math.abs(divisor);
            dividend = Math.abs(dividend);
            while (divisor <= (dividend >> 1)) {
                divisor <<= 1;
                digit++;
            }
            while (digit >= 0) {
                if (dividend >= divisor ) {
                    ret += (1 << digit);
                    dividend -= divisor;
                }
                digit--;
                divisor >>= 1;
            }
            return is_neg ? -1 * ret : ret; 
        }
    }
  • 相关阅读:
    网站如何知道浏览器的用户在使用什么语言?
    安装 Couchbase 服务器
    windows Phone 浏览器窗口的尺寸
    【leetcode】 9. palindrome number
    Android Notification实现推送消息过程中接受到消息端有声音及震动及亮屏提示
    UVA 12487 Midnight Cowboy(LCA+大YY)(好题)
    Jenkins——应用篇——插件使用——Publish over SSH
    Linux经常使用命令(三)
    c++引用总结
    quickcocos2dx framework环境变 fatal error C1083: 无法打开源文件:“.Box2D/Dynamics/b2World.h”: No such file or d
  • 原文地址:https://www.cnblogs.com/airwindow/p/4289573.html
Copyright © 2011-2022 走看看