1. 程式人生 > >LeetCode: 29. Divide Two Integers (Medium)

LeetCode: 29. Divide Two Integers (Medium)

edi tro 大於 sys 復雜 ref 思路 system problems

1. 原題鏈接

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

2. 題目要求

給出被除數dividend和除數divisor,求出二者相除的商,余數忽略不計。

註意:不能使用乘法、除法和取余運算

3. 解題思路

陷阱一:MIN_VALUE/-1會溢出。因為Integer.MIN_VALUE = -的絕對值比Integer.MAX_VALUE大1

陷阱二:除數divisor不能等於“0”


思路一:使用一個while循環,當dividend >= divisor時,進入循環。dividend = divident - divisor,每減一次計數器res+1。循環結束後則得到二者之商。

缺點:時間復雜度為O( n ),當被除數很大、除數很小時,效率非常低

 3 public class DivideTwoIntegers29 {
 4     public static void main(String[] args) {
 5         System.out.println(divided(-36, -3));
 6     }
 7 
 8     public static int divide(int dividend, int divisor) {
 9         if (divisor == 0 || dividend == Integer.MIN_VALUE && divisor == -1)
10 return Integer.MAX_VALUE; 11 int res = 0; 12 int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1; // 異或運算,除數和被除數同號為正,異號為負 13 long dvd = Math.abs((long) dividend); 14 long dvs = Math.abs((long) divisor); 15 while (dvd >= dvs) { 16 dvd -= dvs;
17 res++; 18 }
19 return sign == 1 ? res : -res; 20 } 21 }


思路二:采用位移運算,任何一個整數可以表示成以2的冪為底的一組基的線性組合,即num=a_0*2^0+a_1*2^1+a_2*2^2+...+a_n*2^n。基於以上這個公式以及左移一位相當於乘以2,我們先讓除數左移直到大於被除數之前得到一個最大的基。然後接下來我們每次嘗試減去這個基,如果可以則結果增加加2^k,然後基繼續右移叠代,直到基為0為止。因為這個方法的叠代次數是按2的冪直到超過結果,所以時間復雜度為O(logn)

 1 public class DivideTwoIntegers29 {
 2     public static void main(String[] args) {
 3         System.out.println(divided(-36, -3));
 4     }
 5 
 6     public static int divide(int dividend, int divisor) {
 7         if (divisor == 0 || dividend == Integer.MIN_VALUE && divisor == -1)
 8             return Integer.MAX_VALUE;
 9         int res = 0;
10         int sign = (dividend < 0) ^ (divisor < 0) ? -1 : 1; // 異或運算,除數和被除數同號為正,異號為負
11         long dvd = Math.abs((long) dividend);
12         long dvs = Math.abs((long) divisor);
13         while (dvs <= dvd) {
14             long temp = dvs, mul = 1;
15             while (dvd >= temp << 1) {  // temp<<1,二進制表示左移一位,等價於temp乘以2
16                 temp = temp << 1;
17                 mul = mul << 1;
18                 System.out.println("temp = " + temp + "  " + "mul = " + mul);
19             }
20             dvd -= temp;
21             System.out.println("dvd" + dvd);
22             res += mul;
23         }
24         return sign == 1 ? res : -res;
25     }
26 }

LeetCode: 29. Divide Two Integers (Medium)