zoukankan      html  css  js  c++  java
  • [Swift]LeetCode29. 两数相除 | Divide Two Integers

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址:https://www.cnblogs.com/strengthen/p/9894980.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

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

    Return the quotient after dividing dividend by divisor.

    The integer division should truncate toward zero.

    Example 1:

    Input: dividend = 10, divisor = 3
    Output: 3

    Example 2:

    Input: dividend = 7, divisor = -3
    Output: -2

    Note:

    • Both dividend and divisor will be 32-bit signed integers.
    • The divisor will never be 0.
    • Assume we are dealing with an environment which could only store integers within the 32-bit signed integer range: [−2^31,  2^31 − 1]. For the purpose of this problem, assume that your function returns 2^31 − 1 when the division result overflows.

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

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

    示例 1:

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

    示例 2:

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

    说明:

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

    8ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         if divisor == Int32.min {
     4             return dividend == Int32.min ? 1 : 0    
     5         }
     6         var dividend = dividend
     7         var divisor = divisor
     8         var hasSign = (dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0)
     9         var extra = 0
    10         if dividend == Int32.min {
    11             if divisor == -1 {
    12                 return Int(Int32.max)
    13             } else if divisor > 0 {
    14                 dividend += divisor
    15             } else {
    16                 dividend -= divisor
    17             }
    18             extra += 1
    19         }
    20         
    21         
    22         let result = dividePositive(abs(dividend), abs(divisor)) + extra
    23         return hasSign ? -result : result
    24     }
    25     
    26     func dividePositive(_ dividend: Int, _ divisor: Int) -> Int {
    27         var first = dividend
    28         var second = divisor
    29         var power = 0
    30         var result = 0
    31         
    32         while (first - second >= second) {
    33             second <<= 1
    34             power += 1
    35         }
    36         
    37         while first >= second {
    38             result += (1 << power)
    39             first -= second
    40             while power > 0 && first < second {
    41                 power -= 1
    42                 second >>= 1
    43             }
    44         }
    45         return result
    46     }
    47 }

    16ms

     1 class Solution {
     2      func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         var quocient : Int = 0
     4         var currentDivident = abs(dividend)
     5         let currentDivisor = abs(divisor)
     6         
     7         if currentDivisor == 1 {
     8             if divisor < 0 {
     9                 currentDivident *= -1
    10             }
    11             if dividend < 0 {
    12                 currentDivident *= -1
    13             }
    14             currentDivident = analiseLimits(quocient: currentDivident)
    15             return currentDivident
    16         }
    17         
    18         var iCount = 0
    19         
    20         for i in 1...currentDivident {
    21             if (currentDivident - currentDivisor * i) >= 0 {
    22                 quocient += i
    23                 iCount = i
    24                 currentDivident -= currentDivisor * i
    25             } else {
    26                 break
    27             }
    28         }
    29         
    30         while currentDivident >= currentDivisor {
    31             while currentDivident >= currentDivisor * iCount {
    32                 quocient += iCount
    33                 currentDivident -= currentDivisor * iCount
    34             }
    35             iCount -= 1
    36             if iCount == 0 {
    37                 break
    38             }
    39         }
    40         
    41         
    42         quocient = invert(quocient: quocient, dividend: dividend, divisor: divisor)
    43         quocient = analiseLimits(quocient: quocient)
    44         
    45         return quocient
    46     }
    47     
    48     func invert(quocient: Int, dividend: Int, divisor: Int) -> Int {
    49         var newQuocient = quocient
    50         if dividend < 0 {
    51             newQuocient *= -1
    52         }
    53         if divisor < 0{
    54             newQuocient *= -1
    55         }
    56         return newQuocient
    57     }
    58     
    59     func analiseLimits(quocient: Int) -> Int {
    60         var newQuocient = quocient
    61         if quocient > 2147483647 {
    62             print(quocient)
    63             newQuocient = 2147483647
    64         } else if quocient < -2147483648 {
    65             newQuocient = -2147483648
    66         }
    67         return newQuocient
    68     }
    69 }

    20ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         if divisor == 0 {
     4             return Int.max - 1
     5         }
     6         
     7         let isNegative = (dividend < 0) != (divisor < 0)
     8         var dividend = abs(dividend)
     9         var divisor = abs(divisor)
    10         var count = 0
    11         
    12         while dividend >= divisor {
    13             var shift = 0
    14             
    15             while dividend >= (divisor << shift) {
    16                 shift += 1
    17             }
    18             
    19             dividend -= divisor << (shift - 1)
    20             count += 1 << (shift - 1)
    21         }
    22         if count >= 2147483648 && !isNegative{
    23             return 2147483647
    24         }
    25         return isNegative ? -count : count
    26     }
    27 }

     20ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         let isNegative = (dividend > 0 && divisor < 0) || (dividend < 0 && divisor > 0)
     4         guard dividend != divisor else { return 1 }
     5         guard dividend != 0 else { return 0 }
     6         var y = abs(divisor)
     7         var x = abs(dividend)
     8         if dividend == Int(Int32.max), y == 1 {
     9             return isNegative ? -Int(Int32.max) : dividend
    10         }
    11         if dividend == Int(Int32.min), y == 1 {
    12             return isNegative ? Int(Int32.min) : Int(Int32.max)
    13         }
    14         guard y != x else { return -1 }
    15         var count = 0
    16         while (x > y) {
    17             var i = 1
    18             var j = 0
    19             while (x >= y << 1) {
    20                 y = y << 1
    21                 i = i << 1
    22                 j += 1
    23             }
    24             x -= y
    25             y = y >> j
    26             count += i
    27         }
    28         return isNegative ? -count : count
    29     }
    30 }

    20ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         if dividend == -2147483648 && divisor == -1 {return 2147483647}
     4         var flag:Int = 1,ans:Int = 0
     5         if dividend == 0 {return 0}
     6         else if divisor == 1 {return dividend}
     7         else if divisor == -1 {return -dividend}
     8         
     9         var long_dividend:Int64 = Int64(dividend)
    10         var long_divisor:Int64 = Int64(divisor)
    11         
    12         if long_dividend < 0 && divisor < 0
    13         {
    14             long_dividend = -long_dividend
    15             long_divisor = -long_divisor
    16         }
    17         else if long_dividend < 0 || long_divisor < 0
    18         {
    19             flag = -1
    20             long_dividend = abs(long_dividend)
    21             long_divisor = abs(long_divisor)
    22         }
    23         
    24         if long_dividend < long_divisor {return 0}
    25         var k:Int = 1
    26         var tmp:Int64 = long_divisor
    27         while (tmp << 1 < long_dividend && tmp << 1 > 0)
    28         {
    29             tmp <<= 1
    30             k <<= 1
    31         }
    32         ans += k
    33         long_dividend -= tmp
    34         
    35         while (long_dividend >= long_divisor)
    36         {
    37             while (tmp > long_dividend)
    38             {
    39                 k >>= 1
    40                 tmp >>= 1
    41             }
    42             long_dividend -= tmp
    43             ans += k
    44         }
    45         return flag * ans
    46     }
    47 }

    24ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         let sign: Int64 = (dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0) ? 1 : -1
     4         let lDividend = dividend < 0 ? -Int64(dividend) : Int64(dividend)
     5         let lDivisor = divisor < 0 ? -Int64(divisor) : Int64(divisor)
     6         var result: Int64 = 0
     7         var left: Int64 = 1
     8         var right: Int64 = lDividend
     9         var middle: Int64 = 0
    10         
    11         while left <= right {
    12             middle = (left + right) / 2
    13             if middle * lDivisor <= lDividend {
    14                 result = middle
    15                 left = middle + 1
    16             } else {
    17                 right = middle - 1
    18             }
    19         }
    20         
    21             if Int(result * sign) >= 2147483648 {
    22                 return 2147483647
    23             } else {
    24                 return Int(result * sign)
    25             }
    26     }
    27 }

    24ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         if dividend == 0{
     4             return 0;
     5         }
     6         var isNeed = false
     7         var dividend = dividend;
     8         var divisor = divisor;
     9         if dividend > 0 && divisor < 0{
    10             isNeed = true
    11             divisor = 0 - divisor;
    12         }else if dividend < 0 && divisor > 0{
    13             isNeed = true
    14             dividend = 0 - dividend;
    15         }else if dividend < 0 && divisor < 0{
    16             divisor = 0 - divisor;
    17             dividend = 0 - dividend;
    18         }
    19         if divisor == 1{
    20             
    21             if isNeed {
    22                 return Int(Int32(0 - dividend));
    23             }else{
    24                 if dividend >= 2^31{
    25                     return Int(Int32.max)
    26                 }
    27                 return Int(Int32(dividend));
    28             }
    29         }
    30         var i = 0;
    31         while divisor <= dividend {
    32             var temp = divisor;
    33             var cnt = 1;
    34             while dividend >= temp{
    35                 temp = temp<<1
    36                 cnt = cnt<<1
    37             }
    38             i += (cnt>>1)
    39             dividend -= (temp>>1)
    40         }
    41         if isNeed {
    42             return Int(0 - i);
    43         }else{
    44             return Int(i);
    45         }
    46     }
    47 }

    28ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         if divisor == 0 || (dividend == -Int(INT32_MAX) - 1 && divisor == -1) {
     4             return Int(INT32_MAX)
     5         }
     6         
     7         var a = abs(dividend), b = abs(divisor), res = 0
     8         let sign = (dividend > 0 && divisor > 0 || dividend < 0 && divisor < 0) ? 1 : -1
     9         if b == 1 {
    10             return a * sign
    11         }
    12         
    13         
    14         while a >= b {
    15             var m = b, n = 1
    16             while (a >= (m << 1)) {
    17                 m <<= 1
    18                 n <<= 1
    19             }
    20             res += n
    21             a -= m
    22         }
    23         
    24         return res * sign
    25     }
    26 }

    32ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         
     4         guard dividend != 0 else {
     5             return 0
     6         }
     7         
     8         guard divisor != 0 else {
     9             return Int(Int32.max)
    10         }
    11         
    12         guard divisor != 1 else {
    13             return dividend
    14         }
    15         
    16         guard divisor != -1 else {
    17             if dividend == Int32.min {
    18                 return Int(Int32.max)
    19             }
    20             
    21             return dividend * -1
    22         }
    23         
    24         let isNegative = ((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0))
    25         
    26         var tmpDividend = abs(dividend)
    27         let tmpDivisor = abs(divisor)
    28         var result = 0
    29         var fac = 1
    30         var incDivisor = tmpDivisor
    31         
    32         while tmpDividend >= tmpDivisor {
    33             if tmpDividend < incDivisor {
    34                 incDivisor = tmpDivisor
    35                 fac = 1
    36             }
    37             
    38             tmpDividend -= incDivisor
    39             
    40             result += fac
    41             
    42             incDivisor += incDivisor
    43             fac += fac
    44         }
    45         
    46         return isNegative ? result * -1 : result
    47     }
    48 }

    44ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         
     4         /// 被除数为0,结果肯定是0
     5         guard dividend != 0 else {
     6             return 0
     7         }
     8         
     9         /// 除数为0,返回32位最大值
    10         guard divisor != 0 else {
    11             return Int(Int32.max)
    12         }
    13         
    14         /// 除数为1,直接返回
    15         guard divisor != 1 else {
    16             return dividend
    17         }
    18         
    19         /// 除数为-1
    20         guard divisor != -1 else {
    21             /// 被除数为-1,结果会越界,则返回32位最大值
    22             if dividend == Int32.min {
    23                 return Int(Int32.max)
    24             }
    25             
    26             /// 直接取反
    27             return dividend * -1
    28         }
    29         
    30         /// 记录一下是否是负数
    31         let isNegative = ((dividend < 0 && divisor > 0) || (dividend > 0 && divisor < 0))
    32         
    33         var tmpDividend = abs(dividend)     // 取正数,方便计算
    34         let tmpDivisor = abs(divisor)       // 取正数,方便计算
    35         var result = 0                      // 商,结果
    36         var fac = 1                         // 除数的倍数,指数式的增长,减小循环的次数
    37         var incDivisor = tmpDivisor         // 真正用来作为减数的数
    38         
    39         // 只有在被除数大于除数的时候才能进入循环
    40         while tmpDividend >= tmpDivisor {
    41             // 当被除数比减数还小,那么重置减数
    42             if tmpDividend < incDivisor {
    43                 incDivisor = tmpDivisor
    44                 fac = 1
    45             }
    46             
    47             // 减去减数
    48             tmpDividend -= incDivisor
    49             
    50             // 对商进行累加
    51             result += fac
    52             
    53             // 指数式的增长减数
    54             incDivisor += incDivisor
    55             fac += fac
    56         }
    57         
    58         return isNegative ? result * -1 : result
    59     }
    60 }

    48ms

     1 class Solution {
     2     func divide(_ dividend: Int, _ divisor: Int) -> Int {
     3         let div = dividend < 0 ? -dividend : dividend
     4         let dsr = divisor < 0 ? -divisor : divisor
     5         
     6         guard div >= dsr else {
     7             return 0
     8         }
     9         
    10         var lfmove = 1
    11         while (dsr<<lfmove) < div  {
    12             lfmove += 1
    13         }
    14         
    15         var res = 1<<lfmove
    16         var sum = dsr<<lfmove
    17         while lfmove > 0 {
    18             lfmove -= 1
    19             if sum > div {
    20                 sum -= (dsr<<lfmove)
    21                 res -= (1<<lfmove)
    22             }
    23             else {
    24                 sum += (dsr<<lfmove)
    25                 res += (1<<lfmove)
    26             }
    27         }
    28         
    29         res = sum > div ? res - 1 : res
    30         res = (dividend > 0 && divisor > 0) || (dividend < 0 && divisor < 0) ? res : -res
    31         res = res > Int32.max ? Int(Int32.max) : res
    32         res = res < Int32.min ? Int(Int32.min) : res
    33        
    34         return res
    35     }
    36 }
  • 相关阅读:
    (剑指offer)斐波那契数列
    手写Vue源码 watch的实现
    Vue源码之异步批量任务更新
    手写Vue源码之 依赖收集
    C# 测试代码#if DEBUG使用
    shell脚本编程相关7
    C#中关于ref和out的认识
    shell脚本编程相关6
    shell脚本编程相关5
    shell脚本编程相关4
  • 原文地址:https://www.cnblogs.com/strengthen/p/9894980.html
Copyright © 2011-2022 走看看