【Leetcode 29】Divide Two Integers 不需要long的方法
【Description】
Divide two integers without using multiplication, division and mod operator.
If it is overflow, return MAX_INT.
用例:
-2147483648 -2147483648
1 1
12 0
99 10
199999 1000
283923892 238923
-9 -10
9 10
-9 1
2147483647 1
-2147483648 1
-2147483648 -1
1 -1
-1 1
-1 -1
【Solution】
方法其实可以说是很low了,甚至可以说是面向用例的编程。 甚至让我一度跑去翻了汇编原理的书。
但是很奇妙的是结果跑到了90.68%前面。

题目说两个整数相除,一般人的做法都是:更大的整数类型。我就不相信了,应该有个不用long long的方法吧。
问题主要在我们把输入a,b都转成绝对值,然后进行移位计算除法,这样就会导致无法用INT_MIN的绝对值了(溢出了,-INT_MIN照样是INT_MIN)。
C++里移位直接就变成了int, 不能变成long long的类型。
这样,解决的方法是:
1. 对INT_MIN不能比较的特例进行表示, 对其他任何样例都可以正常编程。
2. 用unsigned int 将a, b进行转换,就可以表示INT_MAX了。比如 INT_MIN 转换成 1 << 31 的正整数形式, 而且用 unsigned int a = 1 << 31, 会有 a > INT_MAX。如果不转只能是a < INT_MAX甚至 a < 0。
#include<iostream> #include<limits.h> using namespace std; class Solution { public: int divide(int a, int b) { if (b == 0 || (a == INT_MIN && b == -1)) { return INT_MAX; } if (a == INT_MIN && a == b) { return 1; } if (a == 0) { return 0; } int k = 1; if (a < 0 && b > 0) { k = -1; } else if (a > 0 && b < 0) { k = -1; } unsigned int dvd = a > 0 ? a : -a; unsigned int dvs = b > 0 ? b : -b; int div = 0, res = 0; // 强制设置dvd成unsigned int,在使用>=运算符时,会按照unsigned进行比较,这样可以表示1<<31 即 INT_MAX+1且其大于其它数(都<=INT_MAX) while (dvd >= dvs) { div = 0; while (dvd >= (dvs << div) && div < 31) { div++; } div--; dvd = dvd - (dvs << div); res += 1 << div; } res = k == 1 ? res : -res; return res; } }; int main() { Solution sol; int x, y;while (cin >> x >> y) cout << sol.divide(x, y) << endl; return 0; }
 
                    
                     
                    
                 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号