问题描述  

  给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。

  返回被除数 dividend 除以除数 divisor 得到的商。

  示例 1:

  输入: dividend = 10, divisor = 3
  输出: 3

  示例 2:

  输入: dividend = 7, divisor = -3
  输出: -2

  说明:

  • 被除数和除数均为 32 位有符号整数。
  • 除数不为 0。
  • 假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−231,  231 − 1]。本题中,如果除法结果溢出,则返回 231 − 1。

这个问题涉及到了计算机如何利用逻辑运算和加减法来求得除法,这个问题之前一度困扰了我很久。

  

	/**
* 逼近
* 先定符号
* 结果是正是负还是0?
* @param dividend
* @param divisor
* @return
*/
public static int divide(int dividend, int divisor) {
if (dividend == 0) {
return 0;
}
if (dividend == Integer.MIN_VALUE && divisor == -1) {
return Integer.MAX_VALUE;
}
if (divisor == -1) {
return -dividend;
}
if (divisor == 1) {
return dividend;
}
int res = 0, Sum = 0;
    boolean plus = false;
     //同号
    if ((dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0)) {
      plus = true;
     }
   //将两个数都变成负数
   dividend = dividend > 0 ? ~dividend + 1 : dividend;
   divisor = divisor > 0 ? ~divisor + 1 : divisor;
  for (int i = 30; i > -1; i--) {
       //被加数未溢出 加之后的结果未溢出 加之后的结果小于被除数
  int addNum = divisor<<i;
  if (addNum>>i == divisor && Sum + addNum < 0 && Sum + addNum >= dividend) {
  Sum += addNum;
  res += plus ? 1<<i : -1<<i;
  }
  }return res;
}

  

   题解(写代码时候的奇怪想法。。。):

    首先进行边界处理之类的。

    一开始我采用了二分法猜数字,首先做一个记号记录结果,然后把被除数(dividend)和除数(divisor)都转换为正数 (信息加工),这样结果就一定是在[0,dividend]。

    初始化left = 0, right = dividend,mid = dividend << 1;

    然后通过for循环累加mid次验证是否符合结果( mid * divisor <= dividend并无法取到比mid更大的mid'去满足前面条件);

    由于平时并不是经常使用二分碰到了以下问题:

      二分的边界问题:

        如何写出不杂乱的代码?

        因为常常使用 mid = (left + right)<<1;

        故而遗忘了mid还可以向右偏 mid = ((left + right)<<1) + 1;。

      因为要保证结果一定在边界内,故而

        left = mid + 1; right = mid - 1;常常不能同时出现(视情况而定吧)。

      所以有时候

        采用 right = mid - 1; left = mid;这个组合时:

        mid = (left + right)<<1; (left + 1 = right) 时候回卡死!

        这个时候要mid  = ((left + right)<<1) + 1;(向右偏)

  当然这样的思路写出来的代码的结果就是我挂了。。

    for循环累加代替乘法实在太慢了!!!

  然鹅,这时候我想到了一个办法。

    divisor * mid 可以写成 divisor (m0 * 2^31 + m1 * 2^30 + m2 * 2^31 ....+m30 * 2^0)

    然后二的m次方这个东西我是可以通过左移来得到的!

    于是我兴奋地用这个方法验证mid对不对。

  发现很多边界问题无法解决

  例如:

    之前说的右偏碰到Integer.MIN_VALUE

    Integer.MIN_VALUE无法转换为正数

    mid取得太大,数据溢出,本来divisor * mid已经超过了Integer.MAX_VALUE。却还是几千。。。

  于是我处于崩溃的边缘。。。

    这样搞下去我要屎了!

  然鹅,解手的时候。我想:

    我可以把所有数都转换为负数先啊

    我可以不用猜测mid是多少啊

    我直接从一步一步逼近被除数就行啦??? 好像真的是。。

    例如 :

      结果如若为101010111...(32位)

    那么我从头开始的非符号位开始看能不能加进去就好啦! 如若能加进去就逼近了被除数,数据本身溢出,加进去溢出,加进去大于被除数就代表不能加!

    其他的都加,反正我要的也是最逼近的数。。。

leetcode 29 两数相除的更多相关文章

  1. Java实现 LeetCode 29 两数相除

    29. 两数相除 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商 ...

  2. Leetcode 29.两数相除 By Python

    给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...

  3. LeetCode 29 - 两数相除 - [位运算]

    题目链接:https://leetcode-cn.com/problems/divide-two-integers/description/ 给定两个整数,被除数 dividend 和除数 divis ...

  4. [LeetCode]29 两数相除和一个小坑点

    给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor 得到的商. 示例 1: 输 ...

  5. LeetCode 29——两数相除

    1. 题目 2. 解答 2.1. 方法一 题目要求不能使用乘法.除法和除余运算,但我们可以将除法转移到对数域. \[ \frac{a}{b} = e^{\frac{lna}{lnb}} = e^{ln ...

  6. leetcode 29两数相除

    我理解本题是考察基于加减实现除法,代码如下: class Solution { public: //只用加减号实现除法, //不用加减号实现除法: int divide(int dividend, i ...

  7. 【剑指 Offer II 001. 整数除法】同leedcode 29.两数相除

    剑指 Offer II 001. 整数除法 解题思路 在计算的时候将负数转化为正数,对于32位整数而言,最小的正数是-2^31, 将其转化为正数是2^31,导致溢出.因此将正数转化为负数不会导致溢出. ...

  8. [LeetCode] 29. Divide Two Integers 两数相除

    Given two integers dividend and divisor, divide two integers without using multiplication, division ...

  9. LeetCode(29): 两数相除

    Medium! 题目描述: 给定两个整数,被除数 dividend 和除数 divisor.将两数相除,要求不使用乘法.除法和 mod 运算符. 返回被除数 dividend 除以除数 divisor ...

随机推荐

  1. 什么是JS跨域请求

    这里说的js跨域是指通过js在不同的域之间进行数据传输或通信,比如用ajax向一个不同的域请求数据,或者通过js获取页面中不同域的框架中(iframe)的数据.只要协议.域名.端口有任何一个不同,都被 ...

  2. ASP.NET第一次访问慢的解决方法(MVC,Web Api)

    问题现象 访问asp.net web项目的时候,第一次访问比较慢,当闲置一段时间后,再次访问还是会非常慢. 问题原因 这是IIS回收造成的,再次访问的时候会初始化操作,初始化需要耗费时间,所以访问会比 ...

  3. MySQL数据库设计与开发规范

    目录 1. 规范背景与目的 2. 设计规范 2.1. 数据库设计 2.1.1. 库名 2.1.2. 表结构 2.1.3. 列数据类型优化 2.1.4. 索引设计 2.1.5. 分库分表.分区表 2.1 ...

  4. 《转载黑马教程》HTML&&CSS讲义0,,包含教程_仅供参考

    今日内容 1. web概念概述 2. HTML web概念概述 * JavaWeb: * 使用Java语言开发基于互联网的项目 * 软件架构: 1. C/S: Client/Server 客户端/服务 ...

  5. 提高JavaScript 技能的12个概念

    JavaScript 是一种复杂的语言.如果是你是高级或者初级 JavaScript 开发人员,了解它的基本概念非常重要.本文介绍 JavaScript 至关重要的12个概念,但绝对不是说 JavaS ...

  6. springcloud-路由gateway

    1. 场景描述 springcloud刚推出的时候用的是netflix全家桶,路由用的zuul(springcloud-路由Zull),但是据说zull1.0在大数据量访问的时候存在较大性能问题,2. ...

  7. java三大集合遍历

    1. 场景描述 今天需要用到map集合遍历,一下子忘记咋写了,以前一般用map.get()直接获取值,很少遍历map,刚好总结下java中常用的几个集合-map,set,list遍历. 2. 解决方案 ...

  8. cogs426血帆海盗(网络流打法)

    这道题基本上来就能看的出来是网络流但难点在于它的结果貌似与最大流,最小割都没啥关系,我猜不少萌新像我一样想暴力枚举边(要是考试我就真这么做了),但很明显,出题人没打算让你这么水过,100000的数据不 ...

  9. Excel导出功能超时解决方案 -- 异步处理

    背景 有运营同学反馈,最近导出excel会出现超时的情况,初步判断是数据增长太快,数据量太大,请求时间超过了设置的超时时间 尝试 有考虑直接更改该请求的超时时长,可是治标不治本 网上搜索发现,有很多人 ...

  10. 洛谷 P4363 [九省联考2018]一双木棋chess 题解

    题目链接:https://www.luogu.org/problemnew/show/P4363 分析: 首先博弈,然后考虑棋盘的规则,因为一个子在落下时它的上面和左面都已经没有空位了,所以棋子的右下 ...