问题描述:
原因分析:
问题
- 使用绝对值将数变成正的,是有问题的。 将 - 231 转化成正数是 231是超出了题目给的范围的。而为什么要用绝对值呢? 是因为2个数相除,同号的话,商为正;异号的话,商为负。 所以转成正数会越界,就全部转化为负数,进行计算。
- 超时了
class Solution {
public:
//所有乘除法操作都可以转化为加法进行。
int divide(int a, int b) {
if(a == 0){
return a;
}
if(a == INT_MIN && b == -1){
return INT_MAX;
}
int num=0;
//同号 商为正 ; 异号 商为负
int flag=(a>0 && b>0) || (a<0 && b<0);
//先把a,b弄成绝对值
a=-abs(a);
b=-abs(b);
while(a<=b){
a=a-b;
num++;
}
return flag==1? num:-num;
}
};
- 报错:Line 25: Char 29: runtime error: negation of -2147483648 cannot be represented in type ‘int’; cast to an unsigned type to negate this value to itself (solution.cpp)
SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior prog_joined.cpp:34:29
最后一步直接加负号 return flag==1? num:-num; 会导致INT_MIN越界,所以最好单独把这个例子拿出来写。
class Solution {
public:
int divide(int a, int b) {
if(a == INT_MIN && b==1){
return INT_MIN;
}
if(a == INT_MIN && b == -1){
return INT_MAX;
}
int num=0;
//同号 商为正 ; 异号 商为负
int flag=(a>0 && b>0) || (a<0 && b<0);
//a,b换成无符号整数避免越界
unsigned int a1=abs(a);
unsigned int b1=abs(b);
// 每次减去除数的倍数
for(int i=31;i>=0;i--){
if((a1>>i)>= b1){
//如果a1 右移i位之后还大于b1,则a1 一定大于b1左移i位
a1=a1-(b1<<i);
num+=(1<<i);
}
}
return flag==1? num:-num;
}
};
- 无符号整数的范围是 0~ 2n-1. 有符号整数的范围是[-2n-1,2n-1-1]
- 时间复杂度 从 O(n) 下降到O(logn)