给定范围 [m, n],其中 0 <= m <= n <= 2147483647,返回此范围内所有数字的按位与(包含 m, n 两端点)。
链接:https://leetcode-cn.com/problems/bitwise-and-of-numbers-range/
/*
基本思路: 比较m和n的每一位,如果这以为不同,则与之后一定为0,只要变化过则这一位就一定为0
我们如果不同则对m和n的右移来进行比较这一位之前的是否相同,相同表示m和n的范围内这些位数都没有变化过,一旦不同就表示之前某一位变化过就继续比较,不同表示变化过,继续右移比较
最后右移了几位,就左移补0来恢复
m和n假如在最高位到x位之间的二进制位完全相同,这就说明在递增的过程中+1的操作永远没有改变过这些位,而相反第x-1到最后一位都至少改变过一次,而改变一定是0->1或者1->0,就是说在着m-n+1个操作数中至少有一个的第i位(i>=0 && i<=x-1)为0.因此,第x-1位之下全都为0,m和n从最高位开始的连续相同部分就是我们要的结果.
*/
class Solution {
public:
int rangeBitwiseAnd(int m, int n) {
int offset = 0;
while(m && n)
{
if(m==n)
return m<<offset;
m>>=1;
n>>=1;
offset++;
}
return 0;
}
};
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
链接:https://leetcode-cn.com/problems/divide-two-integers
/*基本思想:移位操作,每左移一位相当于数字乘以2
先考虑除法溢出的情况,然后判断符号,两个数变为绝对值进行运算
除数为1单独考虑
其他情况,只要被除数大于等于除数,就用除数不断扩大2倍,直到大于被除数,此时被除数更新被除数-扩大后的除数,然后继续循环操作,直到被除数小于除数
*/
class Solution {
public:
int divide(int dividend, int divisor) {
if(divisor==0 || (dividend==INT_MIN && divisor==-1))
return INT_MAX; //除法溢出情况
int sign = 1;
if((dividend<0 && divisor>0) || (dividend>0&& divisor<0))
sign=-1;
long a = abs((long)dividend);
long b = abs((long)divisor);
long res=0;
long cur = b;
if(b==1)
return sign>0?a:-a;
long cur_res;
while(b<=a){
cur = b;
cur_res = 1;
while(cur<=a) //找到扩大后大于被除数的位置
{
cur<<=1;
// cout<<cur<<endl;
cur_res<<=1;
}
cur>>=1;
cur_res>>=1;
res+=cur_res;
a = a-cur;
}
return sign>0?res:-res;
}
};