[Leetcode] 29. Divide Two Integers 解题报告

来源:互联网 发布:软件硬件什么意思 编辑:程序博客网 时间:2024/05/29 19:57

题目

Divide two integers without using multiplication, division and mod operator.

If it is overflow, return MAX_INT.

思路

        我们在这里总结一下两种可能的思路(只考虑被除数和除数均为正数的情况):

1、只要被除数大于等于除数,就从被除数中减去除数,每减去一次结果就增加1。假设最终结果为n,则该算法的时间复杂度为O(n)。

2、只要被除数大于等于除数的2倍,我们就将除数和结果均乘以2,直到被除数小于除数的2倍。接着将被除数更新为被除数与除数的差,将除数恢复为最初的除数,并重复上述操作直到被除数小于除数。此时算法的时间复杂度降为O(logn)。

       O(logn)的复杂度要比O(n)好不少的。而这刚好涉及到几何级数和代数级数的概念。因为思路1中被除数是以代数级数的速度下降的,所以其时间复杂度为O(n);而思路2中除数是以几何级数的速度增长的,所以迭代中被除数也就是以几何级数的速度下降的,因此其时间复杂度为O(logn)。

       注意上述分析中n并不表示被除数和除数的规模,而是代表结果的规模。这类问题我们一般称为output-sensitive的。

       好多问题都可以从O(n)优化为O(logn),而这也是面试中经常会碰到的问题。我记得中Leetcode中还有好几道题目涉及到这一思想,例如求平方根,求幂等。建议读者把这几道题目结合起来一起练习,加深印象。

代码

class Solution {public:    int divide(int dividend, int divisor)     {        // the only special case that might cause overflow        if(dividend == INT_MIN && divisor == -1)             return INT_MAX;        if(dividend == 0)             return 0;          long ans = 0;        long nums1 = labs(dividend);        long nums2 = labs(divisor);          while(nums2 <= nums1)          {              int cnt = 1;              while((nums2 << cnt) <= nums1)                 cnt++;              ans += (1 << (cnt-1));            nums1 -= (nums2 << (cnt-1));          }          return (dividend > 0 ^ divisor > 0)? -ans : ans;      }};



0 0
原创粉丝点击