目录
学习计划链接
题目解析
1. 剑指 Offer II 001. 整数除法
1) 问题描述
2) 思路分析
先转化为正数,找到a能被b乘的最小二次幂k,将剩余的a-b*k再和b进行运算,累加结果即可
3) leetcode链接
4) 代码实现
class Solution {
public:
int divide(int a, int b) {
if( a==0 )//分子为0的情况
return 0;
if( a==INT_MIN && b==-1 )
return INT_MAX;
if( a==INT_MIN && b==1 )
return INT_MIN;
bool signal=(a>0) ^ (b>0); //预先判断结果的符号
long long aPlus=abs(a);
long long bPlus=abs(b);
int ans=0;
/*
aPlus<bPlus返回0
否则不断左移一位bPlus,直到bBlus刚好大于bPlus
*/
while( aPlus >= bPlus ){
int cnt=0; //左移次数
while( aPlus >= ( bPlus << cnt ) ){
++cnt;
}
//因为 bPlus * ( 1<<(cnt-1) )是小于aPlus的
ans += ( 1<<(cnt-1)); //累加结果
aPlus -= ( bPlus << (cnt-1) ); //更新aPlus
}
return signal ? -ans : ans;
}
// int divide(int a, int b) {
// //-2^31/-1=2^31——————溢出
// if(a==0x80000000&&b==-1)
// {
// return 0x7FFFFFFF;
// }
// //1. 将负数转为正数——存在越界,因此将正数转为负数,并记录负数个数;
// int num=2;
// if(a>0)
// {
// a=-a;
// num--;
// }
// if(b>0)
// {
// b=-b;
// num--;
// }
// //2. 进行除法计算
// long long ret=0;
// while(a<=b){
// a-=b;
// ret++;
// }
// //3.判断值的正负。通过num奇偶
// if(num%2!=0)
// ret=(int)-ret;
// return ret;
// }
// int divide(int a, int b) {
// //-2^31/-1=2^31——————溢出
// if(a==0x80000000&&b==-1)
// {
// return 0x7FFFFFFF;
// }
// //1. 将负数转为正数,并记录负数个数;
// int num=0;
// if(a<0)
// {
// a=-a; //-2^31存在越界
// num++;
// }
// if(b<0)
// {
// b=-b;
// num++;
// }
// //2. 进行除法计算
// int ret=0;
// while(a>=b){
// a-=b;
// ret++;
// }
// //3.判断值的正负。通过num奇偶
// if(num%2!=0)
// ret=-ret;
// return ret;
// }
};
2. 剑指 Offer II 002. 二进制加法
1) 问题描述
2) 思路分析
双指针 + 进位加法逻辑
- 双指针, 让两个数的末位对齐, 两个指针 i, j均从各自字符串的末尾开始走。
- 定义一个string res 来存放结果, 一个int carry来记录每位的进位值, 初始值设为0。
- 计算当前位置的数时, sum = a[i] + b[j] + carry, 每趟都要记得更新carry的值。
- 循环结束时, 由于低位的数字字符先加到了结果字符串中, 最后还需要 reverse 一次, 让位置恢复正常。
3) leetcode链接
4) 代码实现
class Solution {
public:
string addBinary(string a, string b) {
string ret;
int i=a.size()-1;
int j=b.size()-1;
int carry=0; //进位
while(i>=0 ||j>=0)
{
//1. 从低位开始,将字符转为数字,求和sum=dig_a+dig_b+carry。
int dig_a=i>=0?a[i--]-'0':0;
int dig_b=j>=0?b[j--]-'0':0;
int sum =dig_a+dig_b+carry;
//2. 更新carry,将sum更新为合适的数
carry=sum>=2?1:0;
sum = sum>=2?sum-2:sum;
//3.插入返回值
ret.append(to_string(sum));
}
if(carry==1)
{
ret.push_back('1');
}
reverse(ret.begin(),ret.end());
return ret;
}
};
3. 剑指 Offer II 003. 前 n 个数字二进制中 1 的个数
1) 问题描述
2) 思路分析
第一种:动态规划:
dp定义–dp[i]表示数i二进制1的个数,初始化dp[0]=0,我们知道如果数i是偶数,则i/2中1的个数和i中1的个数是一样的,只是位置不同。如果i是奇数,则表示最后一位是1,显然i/2中1的个数需要加上1.
第二种:直接遍历
每个数都求一下1的个数
3) leetcode链接
剑指 Offer II 003. 前 n 个数字二进制中 1 的个数
4) 代码实现
class Solution {
public:
int ToBinary(int x)
{
int res=0;
int i=0;
while(x!=0)
{
res=(x%2)*pow(10,i)+res;
i++;
x/=2;
}
return res;
}
vector<int> countBits(int n) {
vector<int> ret(n+1,0);
for(int i=0;i<=n;i++)
{
if( ( i & 1 ) == 1 )
ret[i]=ret[i/2]+1;
else
ret[i]=ret[i/2];
}
return ret;
}
};
参考链接:
https://leetcode-cn.com/problems/JFETK5/solution/leetcode-ac-qing-xi-yi-dong-de-jie-fa-ha-tqi6/
https://leetcode-cn.com/problems/w3tCBm/solution/liang-chong-fang-fa-du-hao-li-jie-by-wcs-grfi/