29. Divide Two Integers

LeetCode medium original: C# #bit-manipulation #csharp #leetcode #math #medium
Văn bản bài toán được dịch từ tiếng Nga theo ngôn ngữ giao diện. Mã không thay đổi.
given два целых числа: делимое и делитель, разделите два целых числа, не используя операторы умножения, деления и модификатора.

Целочисленное деление должно сокращаться до нуля, что означает потерю дробной части. НаVí dụ, 8,345 будет сокращено до 8, а -2,7335 будет сокращено до -2.

returns частное после деления делимого на делитель.

Примечание. Предположим, мы имеем дело со средой, которая может хранить целые числа только в пределах 32-битного целого диапазона со знаком: [−2^31, 2^31 − 1]. В этой задаче, если частное строго больше 2^31 - 1, return 2^31 - 1, а если частное строго меньше -2^31, return -2^31.

C# lời giải

đã khớp/gốc
public class Solution {
    public int Divide(int dividend, int divisor) {
        if(divisor == 0 || dividend == int.MinValue && divisor == -1) return int.MaxValue;
        
        int sign = (dividend < 0 ^ divisor < 0) ? -1 : 1, result = 0;
        
        long m = Math.Abs((long)dividend), n = Math.Abs((long)divisor);
        
        while(m >= n)
        {
            long subN = n;
            for(int subCount = 1; m >= subN; subCount <<= 1, subN <<= 1)
            {
                m -= subN;
                result += subCount;
            }
        }
        
        return sign == 1 ? result : (result - result - result);
    }
}

C++ lời giải

bản nháp tự động, xem lại trước khi gửi
#include <bits/stdc++.h>
using namespace std;

// Auto-generated C++ draft from the C# solution. Review containers, LINQ and helper types before submit.
class Solution {
public:
    public int Divide(int dividend, int divisor) {
        if(divisor == 0 || dividend == int.MinValue && divisor == -1) return int.MaxValue;
        
        int sign = (dividend < 0 ^ divisor < 0) ? -1 : 1, result = 0;
        
        long m = abs((long)dividend), n = abs((long)divisor);
        
        while(m >= n)
        {
            long subN = n;
            for(int subCount = 1; m >= subN; subCount <<= 1, subN <<= 1)
            {
                m -= subN;
                result += subCount;
            }
        }
        
        return sign == 1 ? result : (result - result - result);
    }
}

Java lời giải

đã khớp/gốc
public int divide(int dividend, int divisor) {
  long result = divideLong(dividend, divisor);
  return result > Integer.MAX_VALUE ? Integer.MAX_VALUE : (int)result;
}

// It's easy to handle edge cases when
// operate with long numbers rather than int
public long divideLong(long dividend, long divisor) {
  
  // Remember the sign
  boolean negative = dividend < 0 != divisor < 0;
  
  // Make dividend and divisor unsign
  if (dividend < 0) dividend = -dividend;
  if (divisor < 0) divisor = -divisor;
  
  // Return if nothing to divide
  if (dividend < divisor) return 0;
  
  // Sum divisor 2, 4, 8, 16, 32 .... times
    long sum = divisor;
    long divide = 1;
    while ((sum+sum) <= dividend) {
      sum += sum;
      divide += divide;
    }
    
    // Make a recursive call for (devided-sum) and add it to the result
    return negative ? -(divide + divideLong((dividend-sum), divisor)) :
      (divide + divideLong((dividend-sum), divisor));
}

JavaScript lời giải

đã khớp/gốc
var divide = function(dividend, divisor) {    if(dividend===0) return 0;
    let signal = 1;    if(dividend<0){
        signal *= -1;    }
    if(divisor<0){        signal *= -1;
    }    dividend = Math.abs(dividend);
    divisor = Math.abs(divisor);    
    let result = help(dividend, divisor)*signal;    if(result>Math.pow(2,31)-1){
        result = Math.pow(2,31)-1;    }else if(result<-1*Math.pow(2,31)){
        result = Math.pow(2,31)*(-1);    }
    return result;    
        function help(dividend, divisor){            if(dividend < divisor) return 0;
            let res = 0;            let origDivisor = divisor;
            let prev = 0;            while(dividend>=divisor){
                if(res===0){                    res += 1;
                }else{                    res += res;
                }                prev = divisor;
                divisor += divisor;            }
            dividend -= prev;            res += help(dividend, origDivisor);
            return res;        }
};

Python lời giải

đã khớp/gốc
class Solution(object): 
    def divide(self, dividend, divisor): 
        """ 
        :type dividend: int 
        :type divisor: int 
        :rtype: int 
        """ 
        if abs(divisor) == 1: 
            dividend = divisor * dividend 
            if dividend > 2**31 - 1: 
                return 2**31 - 1 
 
            if dividend < -2**31: 
                return -2**31 
 
            return dividend 
 
        quotient = 0 
        sign = 1 
        if dividend * divisor < 0: 
            sign = -1 
 
        if dividend < 0: dividend = -dividend 
        if divisor < 0: divisor = -divisor 
 
        i = 1 
        sum_all = 0 
        while sum_all <= dividend: 
            if dividend - sum_all < divisor * i: 
                i = 1 
            quotient += i 
            sum_all += divisor * i 
            i += 1 
 
        return (quotient - 1) * sign

Go lời giải

đã khớp/gốc
func divide(dividend int, divisor int) int {
    c := 0
    dividendS, r := SplitSignAndNum(dividend)
    divisorS, d := SplitSignAndNum(divisor)
    for r >= d {
        r = r - d
        c++
    }
    
    result := c
    
    if dividendS < 0 || divisorS < 0 {
        if !(dividendS < 0 && divisorS < 0) {
            result = -c
        }
    }
    
    if result < -2147483648 {
        return -2147483648
    } else if result > 2147483647 {
        return 2147483647
    }
    
    return result
}

func SplitSignAndNum(i int) (int,int) {
    if i < 0 {
        return -1, -i
    }
    return 1, i
}

Данный код представляет собой класс `Solution`, в котором содержится метод `Divide`, реализующий операцию деления без использования оператора деления. Этот метод выполняет деление `dividend` на `divisor` и returns результат деления. Вот пояснение к данному методу:

1. Метод `Divide` принимает два целых числа `dividend` и `divisor` и returns результат деления `dividend` на `divisor`.

2. В начале метода проверяется специальный случай: если `divisor` равен 0 или если `dividend` равен `int.MinValue` и `divisor` равен -1, то метод returns `int.MaxValue`. Это делается для предотвращения переполнения в случае деления на 0 или разделения `int.MinValue` на -1.

3. Затем определяется знак результата деления на основе знаков `dividend` и `divisor`. Если знаки разные, то результат будет отрицательным, иначе - положительным.

4. Затем переменные `m` и `n` инициализируются как модули от `dividend` и `divisor`, но уже `long`, чтобы избежать переполнения в процессе деления.

5. Запускается цикл `while`, который продолжается, пока `m` больше или равен `n`. Внутри цикла выполняется итеративное вычитание и увеличение результата на основе сдвига влево.

6. Наконец, returnsся результат деления, который корректируется в зависимости от знака в соответствии с вычисленным знаком. Если знак равен -1, результат умножается на -1.

Этот метод реализует Thuật toán вычитания для нахождения результата деления без использования оператора деления, а также управляет специальными случаями, чтобы избежать переполнения.

Vacancies for this task

việc làm đang hoạt động with overlapping task tags are đã hiển thị.

Tất cả việc làm
Chưa có việc làm đang hoạt động.