zoukankan      html  css  js  c++  java
  • [leetcode] Divide Two Integers

    Divide Two Integers
     
    Divide two integers without using multiplication, division and mod operator.
     
    If it is overflow, return MAX_INT.
     
    思路:类似二分查找算法,只不过我们做的是对除数的倍增或者倍减。
    注意点:
    1,提前判断除数与被除数的正负,用来判断最后结果的正负性。
    2,为了防止溢出,将int型转换为long long类型进行运算,最后将结果转换为int型。
    例如:100 / 3
     
    第一步:因为100 > 3, 得到 dividend = 100 - 3 = 97, dividor = 3 + 3 = 6, pre_ret = 1, ret = 1;
    第二步:因为97 > 6, 得到 dividend = 97 - 6 = 91, dividor = 6 + 6 = 12, pre_ret = 1 + 1 = 2, ret = 1 + 2 = 3;
    第三步:因为91 > 12, 得到 dividend = 79, dividor = 24, pre_ret = 4, ret = 7;
    第四步:因为79 > 24, 得到 dividend = 55, dividor = 48, pre_ret = 8, ret = 15;
    第五步:因为55 > 48, 得到 dividend = 7, dividor = 96, pre_ret = 16, ret = 31;
     
    (因为此时dividend > dividor了,所以dividor的倍增此处结束,接下来做倍减)
    第六步:因为7 < 96, 得到 dividend = 7, dividor = 48, pre_ret = 8, ret = 31;
    第四步:因为7 < 48, 得到 dividend = 7, dividor = 24, pre_ret = 4, ret = 31;
    第四步:因为7 < 24, 得到 dividend = 7, dividor = 12, pre_ret = 2, ret = 31;
    第四步:因为7 < 12, 得到 dividend = 7, dividor = 6, pre_ret = 1, ret = 31;
    第四步:因为7 > 6, 得到 dividend = 1, dividor = 3, pre_ret = 0, ret = 33;
    此时 1 小于最原始的除数3,终止循环,根据除数与被除数的正负关系返回ret值即可。
     
     1 class Solution
     2 {
     3 public:
     4   int divide(int dividend, int dividor)
     5   {
     6     if(dividend == INT_MIN && dividor == -1)
     7       return INT_MAX;
     8  
     9     auto sign = [=] (int x) -> int { return x>0? 1 : -1;};
    10     int p1 = sign(dividend);
    11     int p2 = sign(dividor);
    12  
    13     long long n1 = abs(static_cast<long long>(dividend));
    14     long long n2 = abs(static_cast<long long>(dividor));
    15  
    16     long long ret = 0;
    17     long long pre_ret = 0;
    18     while(n1 >= n2)
    19     {
    20       if(ret == 0 && pre_ret == 0)
    21       {
    22         pre_ret = 1;
    23         ret = 1;
    24       }
    25       else
    26       {
    27         pre_ret += pre_ret;
    28         ret = pre_ret + ret;
    29       }
    30  
    31       n1 -= n2;
    32       n2 += n2;
    33     }
    34  
    35     while(n2 >= abs(static_cast<long long>(dividor)) && n1 >= abs(static_cast<long long>(dividor)))
    36     {
    37       if(pre_ret == 0)
    38       {
    39         ret += 1;
    40         break;
    41       }
    42  
    43       if(n1 < n2)
    44       {
    45         n2 = n2 >> 1;
    46         if(n1 == n2)
    47         {
    48           ret += pre_ret;
    49           break;
    50         }
    51         pre_ret = pre_ret >> 1;
    52       }
    53       else
    54       {
    55         n1 -= n2;
    56         n2 = n2 >> 1;
    57         if(n1 == n2)
    58         {
    59           ret += pre_ret;
    60           break;
    61         }
    62         ret = pre_ret + pre_ret + ret;
    63         pre_ret = pre_ret >> 1;
    64       }
    65     }
    66  
    67     if(p1 == p2)
    68       return ret;
    69     else
    70       return -ret;
    71   }
    72 };
  • 相关阅读:
    Luogu1053 NOIP2005篝火晚会
    BZOJ2151 种树(贪心+堆+链表/wqs二分+动态规划)
    Luogu1155 NOIP2008双栈排序(并查集)
    Luogu1092 NOIP2004虫食算(搜索+高斯消元)
    Codeforces Round#516 Div.1 翻车记
    Luogu1731 NOI1999生日蛋糕(搜索)
    洛谷 P1379 八数码难题 解题报告
    洛谷 P2501 [HAOI2006]数字序列 解题报告
    洛谷 P3143 [USACO16OPEN]钻石收藏家Diamond Collector 解题报告
    洛谷 P2894 [USACO08FEB]酒店Hotel 解题报告
  • 原文地址:https://www.cnblogs.com/lxd2502/p/4386448.html
Copyright © 2011-2022 走看看