29. Divide Two Integers
Целочисленное деление должно сокращаться до нуля, что означает потерю дробной части. Например, 8,345 будет сокращено до 8, а -2,7335 будет сокращено до -2.
Возвращает частное после деления делимого на делитель.
Примечание. Предположим, мы имеем дело со средой, которая может хранить целые числа только в пределах 32-битного целого диапазона со знаком: [−2^31, 2^31 − 1]. В этой задаче, если частное строго больше 2^31 - 1, верните 2^31 - 1, а если частное строго меньше -2^31, верните -2^31.
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++ решение
auto-draft, проверить перед отправкой#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 решение
сопоставлено/оригинал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 решение
сопоставлено/оригинал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 решение
сопоставлено/оригинал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 решение
сопоставлено/оригинал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` и возвращает результат деления. Вот пояснение к данному методу:
1. Метод `Divide` принимает два целых числа `dividend` и `divisor` и возвращает результат деления `dividend` на `divisor`.
2. В начале метода проверяется специальный случай: если `divisor` равен 0 или если `dividend` равен `int.MinValue` и `divisor` равен -1, то метод возвращает `int.MaxValue`. Это делается для предотвращения переполнения в случае деления на 0 или разделения `int.MinValue` на -1.
3. Затем определяется знак результата деления на основе знаков `dividend` и `divisor`. Если знаки разные, то результат будет отрицательным, иначе - положительным.
4. Затем переменные `m` и `n` инициализируются как модули от `dividend` и `divisor`, но уже `long`, чтобы избежать переполнения в процессе деления.
5. Запускается цикл `while`, который продолжается, пока `m` больше или равен `n`. Внутри цикла выполняется итеративное вычитание и увеличение результата на основе сдвига влево.
6. Наконец, возвращается результат деления, который корректируется в зависимости от знака в соответствии с вычисленным знаком. Если знак равен -1, результат умножается на -1.
Этот метод реализует алгоритм вычитания для нахождения результата деления без использования оператора деления, а также управляет специальными случаями, чтобы избежать переполнения.
Вакансии для этой задачи
Показаны активные вакансии с пересечением по тегам задачи.