九日集训(每日打卡)第一天

函数


[371. 两整数之和]

class Solution {
public:
    int getSum(int a, int b) {
        return a + b;
    }
};

​


[面试题 17.01. 不用加号的加法]

常用的运算符共 6 种,分别为与( & )、或( | )、异或( ^ )、取反( ~ )、左移( << )和右移( >> )。

 异或运算的逆运算是它本身,也就是说两次异或同一个数最后结果不变,即 a^b^b=a 。
  
                                        

我们知道计算机在做加法时分为进位位和加法位
加法位用异或门 :相同就是0,不同就是1

进位位用与门:     都是1 才为1

举例

class Solution {
public:
    int add(int a, int b) {
        while(b){
                int x=a^b;
                int y=((unsigned)a&b)<<1;
                a=x;
                b=y;
            }
            return a;
    }
};

剑指 Offer 65. 不用加减乘除做加法

跟上一题一样。

面试题 08.05. 递归乘法

思路:把B拆成二进制

class Solution {
public:
    int multiply(int A, int B) {
        return (B & 1 ? A : 0) + ( B > 1 ? multiply(A + A, B >> 1) : 0);
   }
};

29. 两数相除

class Solution {
public:
    int divide(int x, int y) {
        typedef long long LL;
        if (x == INT_MIN && y == -1) {
            return INT_MAX; //如果除法溢出,返回2 ^ 31 - 1
        }
        
        LL a = abs(x), b = abs(y), ans = 0;
        int sign = x > 0 ^ y > 0 ? -1 : 1;

        while (a >= b) { //当a比b大,说明a/b至少等于1
            LL temp = b, m = 1;
            while (temp << 1 <= a) { //当除数倍增后依然小于被除数
                temp <<= 1; //除数倍增
                m *= 2; //个数倍增
            }
            a -= temp; 
            ans += m;
        }
        return sign * ans;

    }
};

整数的除法

  • 舍入到零: 整数1.25向下舍入得到3  负数-1.25向上舍入得到-3
  • 无符号数/2的k次方:逻辑右移(逻辑右移就是不考虑符号位,右移一位,左边补零即可)
    • 0111/4   7/4 = 1.75       1
    • 即0111>>2 得到0001   1
  • 补码/2的k资方:算数右移(需要考虑符号位,右移一位,若符号位为1,就在左边补1,;否则,就补0)
    • 1001/4    -7/4 = -1.75   1
    • 即1001>>2 得到1110  -2
    • 这时我们发现得到的不是我们要的结果,所以需要在右移之前加上一个偏置量,对于除以2^k这种情况来说,需要增加一个2^k-1这个偏置量(0011)
    • 所以 1001 + 0011 = 1100
    • 1100 >> 2 = 1111 = -1

 50. Pow(x, n)

 

class Solution {
public:
    double myPow(double x, int n) {
        typedef long long LL;
        bool is_minus = n < 0; // 确定符号
        double res = 1;
        for(LL k = abs(LL(n));k;k >>= 1){ // 从第0位开始遍历
            if(k & 1) res *= x;    // 如果是1的话就需要乘以 x 否则的话就不用乘,目的是不用预处理了
            x *= x;         // 到了下一位 x 也要翻倍
        }
        return is_minus ? 1/res : res;;
    }
};

69. Sqrt(x)

二分

class Solution {
public:
    int mySqrt(int x) {
        int l = 0,r = x;
        while(l < r){
            int mid = l + 1ll +r  >> 1;
            if( mid <= x/mid) l = mid;
            else r = mid - 1;
        }
        return r;
    }
};

面试题 16.07. 最大数值

                              Max(a,b) = \frac{((a+b) + abs(a-b))}{2}

类型绝对值位运算
int8_t(var ^ (var >> 7)) - (var >> 7)
int16_t(var ^ (var >> 15)) - (var >> 15)
int16_t(var ^ (var >> 15)) - (var >> 15)
int64_t(var ^ (var >> 63)) - (var >> 63)
class Solution {
public:
    int maximum(int a, int b) {
        long diff = (long)a - (long)b;
        return ((long)a + (long)b + (diff ^ (diff >> 63)) - (diff >> 63)) >> 1;
    }
};

  • 4
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值