题目

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

If it is overflow, return MAX_INT

链接

https://leetcode.com/problems/divide-two-integers/

答案

1、int的最大值MAX_INT为power(2,31)-1 = 2147483647

2、int的最小值MIN_INT为-power(2,31) = -2147483648

3、当MIN_INT除以-1的时候,发生溢出,因为得到的值大于MAX_INT

4、有符号数的最高位为1时,表示负数,所以可以使用异或运算获得商的符号

5、abs的各种版本看这里,double abs(double),long abs(long)竟然在C++中有,其实我想自己写个求绝对值方法的,不过,手抖还是搜了一下abs的原型。

6、这才是重中之重,刚开始看到题目,我不知道怎么用位运算去实现除法,先搜到答案

然后思考其中的原理,为什么可以这么做,思考之后自己才写了代码。

我的推理如下,如有问题,请指出,谢谢。下面我有^表示指数,不要跟C++中的^弄混了。

a = b * x (x为要求的商,等号应该为约等于,其实嘛,应该是a >= b * x && a < b * (x+1))

任何一个整数是可以用二进制表示的,所以x=2^m + 2^n + ...... + 2^t,其中m > n > t,m,n,t为整数。

x还可以这么表示x = 1*2^m + 0 * 2^(m-1) + 1 * 2^(m-2) + ...... + (1或0)*2^0。

事实上x还可以这么表示:

x = (2^k + 2^(k-1) + ...... + 2^0) + (2^t + 2^(t-1) + ...... + 2^0) + ...... + (2^r + 2^(r-1) + ...... + 2^0),其中k > t > ...... > r。

所以 a = b * (2^k + 2^(k-1) + ...... + 2^0) +b *  (2^t + 2^(t-1) + ...... + 2^0) + ...... + b * (2^r + 2^(r-1) + ...... + 2^0).

并且k,t,r等满足以下关系:

b *  (2^t + 2^(t-1) + ...... + 2^0) + ...... + b * (2^r + 2^(r-1) + ...... + 2^0)  < b * (2^k + 2^(k-1) + ...... + 2^0) 

...... + b * (2^r + 2^(r-1) + ...... + 2^0) < b * (2^k + 2^(k-1) + ...... + 2^0)  - b *  (2^t + 2^(t-1) + ...... + 2^0)

第一次是 a - b * (2^k + 2^(k-1) + ...... + 2^0)  = b *  (2^t + 2^(t-1) + ...... + 2^0) + ...... + b * (2^r + 2^(r-1) + ...... + 2^0)

对b进行不断左移,即上式的橙色部分,而并累加位移(2^x')是x的一部分,将a不断减去不断左移后的b,即可得到等式左边的数据。

a - b * (2^k + 2^(k-1) + ...... + 2^0)  < b * (2^k + 2^(k-1) + ...... + 2^0)

即b *  (2^t + 2^(t-1) + ...... + 2^0) + ...... + b * (2^r + 2^(r-1) + ...... + 2^0) < b * (2^k + 2^(k-1) + ...... + 2^0)

这个是必然成立的,如果不成立,则b还可以继续左移,即k的值要比当前达到的k还要大,故每次a处理后的结果会比b处理后的结果要小。

第二次是a - b * (2^k + 2^(k-1) + ...... + 2^0) - b *  (2^t + 2^(t-1) + ...... + 2^0) = ...... + b * (2^r + 2^(r-1) + ...... + 2^0)

蓝色部分为第一次的结果。

推到这里,大家应该懂了

代码

 class Solution {
public:
static const int MAX_INT = ;
static const int MIN_INT = -; int divide(int dividend, int divisor) {
if(dividend == MIN_INT && divisor == -)
{
return MAX_INT;
} long pre = abs((long)dividend);
long post = abs((long)divisor);
int index;
int rem = ; while(pre >= post)
{
long tmp = post;
for(index = ; pre >= tmp; index ++, tmp <<= )
{
pre -= tmp;
rem += ( << index);
}
} return (dividend >> ) ^ (divisor >> ) ? -rem:rem;
}
};

leetcode-【中等题】Divide Two Integers的更多相关文章

  1. 乘风破浪:LeetCode真题_029_Divide Two Integers

    乘风破浪:LeetCode真题_029_Divide Two Integers 一.前言     两个整数相除,不能使用乘法除法和取余运算.那么就只能想想移位运算和加减法运算了. 二.Divide T ...

  2. leetcode面试准备:Divide Two Integers

    leetcode面试准备:Divide Two Integers 1 题目 Divide two integers without using multiplication, division and ...

  3. leetcode第28题--Divide Two Integers

    Divide two integers without using multiplication, division and mod operator. 分析:题目意思很容易理解,就是不用乘除法和模运 ...

  4. 【一天一道LeetCode】#29. Divide Two Integers

    一天一道LeetCode系列 (一)题目 Divide two integers without using multiplication, division and mod operator. If ...

  5. [Leetcode][Python]29: Divide Two Integers

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com' 29: Divide Two Integershttps://oj.leetc ...

  6. LeetCode OJ:Divide Two Integers(两数相除)

    Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...

  7. 【LeetCode】029. Divide Two Integers

    Divide two integers without using multiplication, division and mod operator. If it is overflow, retu ...

  8. 【LeetCode】29. Divide Two Integers

    题意:不用乘除求余运算,计算除法,溢出返回INT_MAX. 首先考虑边界条件,什么条件下会产生溢出?只有一种情况,即返回值为INT_MAX+1的时候. 不用乘除求余怎么做? 一.利用减法. 耗时太长, ...

  9. leetcode 中等题(2)

    50. Pow(x, n) (中等) double myPow(double x, int n) { ; unsigned long long p; ) { p = -n; x = / x; } el ...

  10. leetcode 中等题(1)

    2. Add Two Numbers(中等) /** * Definition for singly-linked list. * struct ListNode { * int val; * Lis ...

随机推荐

  1. 《java编程思想》读书笔记(一)开篇&第五章(1)

    2017 ---新篇章  今天终于找到阅读<java编程思想>这本书方法了,表示打开了一个新世界. 第一章:对象导论 内容不多但也有20页,主要是对整本书的一个概括.因为已经有过完整JAV ...

  2. [java]wordcount程序

    词数统计系统. 作业解析:这次作业的内容是从本地读取一个程序代码,计算出这个程序中的行数,单词数,也可进行拓展. 实现语言:java 编程思路: 程序是由各种单词和符号组成的,单词包括关键字,标识符这 ...

  3. VBA编程常用语句

    .Option Explicit '强制对模块内所有变量进行声明 Option Private Module '标记模块为私有,仅对同一工程中其它模块有用,在宏对话框中不显示 Option Compa ...

  4. 初学Laravel

    之前一直用开tp和ot,本来觉得学会一个tp便可走遍天下,tp的确强大.但后来听到很多同行的同学说他们的公司都开始转型往lv走了,我的同学没有学过lv,然而公司给足时间去让他们去学.当然,缺人可能是占 ...

  5. ecs CentOS 7 安装 mysql (mariadb)

    检查之前是否已经安装 rpm -qa | grep mariadb 如果已安装,卸载 yum remove mysql mysql-server mysql-libs compat-mysql51 开 ...

  6. nginx入门篇----安装、部署、升级

    1.安装前准备工作下载nginx安装包依赖包:gcc pcre pcre-level  zlib zlib-devel openssl openss-level在线依赖包安装命令:yum -y ins ...

  7. C语言实现简单php自定义扩展

    1.下载php源码 下载地址:http://cn2.php.net/get/php-5.6.29.tar.gz/from/this/mirror 传到/usr/local/src/下 上传命令:rz ...

  8. PHPStorm 调式JS /同时调式PHP和jS

    PHPStorm 调式JS /同时调式PHP和jS 一.PHPStorm 调式Javascript 在PHP Storm中创建test.html <!DOCTYPE html> <h ...

  9. ThoughtWorks.QRCode源码

    http://files.cnblogs.com/files/xiaoyu369/ThoughtWorks.QRCode.rar

  10. 【Telnet】使用Telnet协议连接到远程Shell执行脚本

    介绍 本文介绍如何通过Telnet协议连接到远程Shell,执行脚本,并获取执行结果: 相关文章: <[Jsch]使用SSH协议连接到远程Shell执行脚本>http://www.cnbl ...