[Swift]LeetCode29. 兩數相除 | Divide Two Integers
阿新 • • 發佈:2018-11-02
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。
12ms
1 class Solution { 2 func divide(_ dividend: Int, _ divisor: Int) -> Int { 3 return Int(Int32(clamping: dividend / divisor)) 4 } 5 }
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 }