leetcode力扣-剑指offer刷题-day1-001整数除法

由于是第一次使用力扣平台,先花费了一些时间熟悉。选择了第一题(可能最简单),看了看题目和评论区,发现也不是很简单。

剑指 Offer II 001. 整数除法icon-default.png?t=M0H8https://leetcode-cn.com/problems/xoh6Oh/

给定两个整数 a 和 b ,求它们的除法的商 a/b ,要求不得使用乘号 '*'、除号 '/' 以及求余符号 '%' 。

要用除法,而不得使用乘号 '*'、除号 '/' 以及求余符号 '%' ,显然是需要利用加减进行处理的(类似一些计算机硬件)。于是理所应当的用暴力破解试一试。

class Solution {
public:
    int divide(int a, int b) {
       int result=0;
       if(a>0&&b>0){
           while(a-b>=0){
               a=a-b;
               result++;
           }
       }
       if(a<0&&b<0){
           while(a-b<=0){
               a=a-b;
               result++;
           }
       }
       if(a>0&&b<0){
           while(a+b>=0){
               a=a+b;
               result--;
           }
       }
       if(a<0&&b>0){
           while(a+b<=0){
               a=a+b;
               result--;
           }
       }
    return result;
    }
};

提交后出现错误,用例-2147483648;-1,提示Line 14: Char 22: runtime error: signed integer overflow: 2147483647 + 1 cannot be represented in type 'int' (solution.cpp) SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:23:22

应当是没有考虑到如下条件。

整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [−2^31, 2^31−1]。本题中,如果除法结果溢出,则返回 2^31 − 1

 修改后

class Solution {
public:
    int divide(int a, int b) {
       int result=0;
       if(a == INT_MIN){
           if(b==1){
               return INT_MIN;
           }else if(b==-1){
               return INT_MAX;
           }
       }
       if(a>0&&b>0){
           while(a-b>=0){
               a=a-b;
               result++;
           }
       }
       if(a<0&&b<0){
           while(a-b<=0){
               a=a-b;
               result++;
           }
       }
       if(a>0&&b<0){
           while(a+b>=0){
               a=a+b;
               result--;
           }
       }
       if(a<0&&b>0){
           while(a+b<=0){
               a=a+b;
               result--;
           }
       }
    return result;
    }
};

提交以后超出了时间限制 ,修改一下,把四个if合并一下。

注意,用负数进行运算(负数的绝对值比正数表示的范围更大,能够避免越界)

class Solution {
public:
    int divide(int a, int b) {
       int result=0;
       int sign=-1;
       if(a == INT_MIN){
           if(b==1){
               return INT_MIN;
           }else if(b==-1){
               return INT_MAX;
           }
       }
        if(a>0){
            sign=-sign;
            a=-a;
        }
        if(b>0){
            sign=-sign;
            b=-b;
        }
//用负数进行运算(负数的绝对值比正数表示的范围更大,能够避免越界)
        if(a<0&&b<0){
           while(a<=b){
               a-=b;
               result++;
           }
       }
        if(sign>0){
            result=-result;
        }

    return result;
    }
};

还是不中,依旧是会超时,换成Java试试。

class Solution {
    public int divide(int a, int b) {
    int result= 0;
    int sign = 1;
       if(a == Integer.MIN_VALUE){
           if(b==1){
               return Integer.MIN_VALUE;
           }else if(b==-1){
               return Integer.MAX_VALUE;
           }
       }
       if(a>0){
           a=-a;
           sign=-sign;
       }
       if(b>0){
           b=-b;
           sign=-sign;
       }
       if(a<0&&b<0){
           while(a<=b){
               a-=b;
               result++;
           }
       }
        if(sign<0){
            result=-result;
        }
    return result;
    }
}

 竟然过了。

leetcode力扣-剑指offer刷题-day1-001整数除法_第1张图片


 一定要注意数值的取值范围,注意边界值的测试。leetcode力扣-剑指offer刷题-day1-001整数除法_第2张图片



 看看下面大佬的解法。位运算。

  1. 根据 两数 正负号,生成flag的值,以便结果的正负号处理
  2. 给 两数 取绝对值
  3. 减值,若 当前被除数 小于 当前除数,则返回0
  4. 循环计算 结果的绝对值
  • 创建一个变量shift,记录 当前左移位数
  • 若 当前除数 小于 当前被除数,一直左移 当前除数,直到 当前除数 大于等于 当前被除数
  • 记录 当前shift的值,并根据当前shift的值,计算 下一轮循环中的 除数 和 被除数
  1. 根据计算的结果 和 flag,返回正确的结果
class Solution {
    public int divide(int a, int b) {
        if (a == Integer.MIN_VALUE && b == -1) {
            return Integer.MAX_VALUE;
        }

        /*
            判断是否同号,同号则 结果为正数
         */
        boolean flag = false;
        if ((a < 0 && b < 0) || (a > 0 && b > 0)) {
            flag = true;
        }

        long dividend = a > 0 ? -a : a;
        long divisor = b > 0 ? -b : b;
        if (dividend > divisor) {
            return 0;
        }
        /*
            计算 结果的绝对值
         */
        int result = 0;
        int shift = 31;
        while (dividend <= divisor) {
            while (dividend > divisor << shift) {
                shift--;
            }
            dividend -= divisor << shift;
            result += 1 << shift;
        }

        return flag ? result : -result;
    }
}

作者:leetcoder-youzg
链接:https://leetcode-cn.com/problems/xoh6Oh/solution/java-qiao-yong-wei-yun-suan-ji-hu-shuang-ts4k/
来源:力扣(LeetCode)

来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/xoh6Oh 

你可能感兴趣的:(leetcode,算法)