剑指Offer(数据结构与算法面试题精讲)C++版——整数除法
1、面试题1:整数除法
题目:
解法1:暴力法,直接连减,时间复杂度:O(n):
#include <bits/stdc++.h>
using namespace std;
int devide(int dividend,int divisor) {
int result=0;
//注意这里的存在溢出,整数范围:-2^31-2^31-1
if(dividend==0x80000000&&divisor==-1) {
return INT_MAX;
}
while(dividend>divisor) {
dividend-=divisor;
result++;
}
return result;
}
int main() {
cout<<devide(15,2);
}
解法2:仿二分法,每次找2倍乘最接近于被除数的数,然后减去该数,原书说这里的时间复杂度为O(logn),但是其实只是找到了最接近的减数;最坏情况下,如果这里的被除数为n=2^m-1=1+2+4+…+2^(m-1),除数为1,内层循环查找依次对应m-1,m-2,…,2,1,总时间复杂度为:O(m^2),由即m=log2(n+1),从而时间复杂度为O2(logn),也能够起到优化作用。
#include <bits/stdc++.h>
using namespace std;
int devide(int dividend,int divisor) {
const int low_limit=0xc0000000,high_limit=0x40000000;
int result=0;
//注意这里的存在溢出,整数范围:-2^31-2^31-1
if(dividend==INT_MIN&&divisor==-1) {
return INT_MAX;
}
while(dividend>=divisor) {
int tmp=divisor;
int times=1;
//应满足 tmp>= -2^30,防止tmp+tmp负向溢出
//且应满足 tmp<*2^30, 防止tmp+tmp正向溢出
while((tmp>=low_limit) && (tmp<high_limit) && (dividend>=tmp+tmp)) {
tmp+=tmp;
times+=times;
}
result+=times;
dividend-=tmp;
}
return result;
}
int main() {
cout<<devide(15,2);
}