雪国列车》力扣入门-第一站(函数)

在这里插入图片描述

371. 两整数之和
剑指 Offer 65. 不用加减乘除做加法
面试题 17.01. 不用加号的加法

371.两整数之和】面试题 17.01. 不用加号的加法】剑指 Offer 65. 不用加减乘除做加法

给你两个整数 a 和 b ,不使用 运算符 + 和 - ​​​​​​​,计算并返回两整数之和。

示例一:

输入:a = 1, b = 2
输出:3

示例二:

输入:a = 2, b = 3
输出:5

提示:

-1000 <= a, b <= 1000

解法一:直接用‘+’,‘-’;

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

在这里插入图片描述

解法二(对数运算法):

class Solution {
public:
    int getSum(int a, int b) {
        return log2(exp2(a)*exp2(b));
    }
};

在这里插入图片描述

解法三:位运算法:

非递归

class Solution {
public:
typedef unsigned int ui;
    int getSum(int a, int b) {
    while(b){
        ui tmp=(ui)(a&b)<<1;
        a^=b;
        b=tmp;
    }
    return a;
    }
};

递归:

class Solution {
public:
    int getSum(int a, int b) {
    return !b?a:getSum(a^b,(unsigned int)(a&b)<<1);
    }
};

在这里插入图片描述

解法四(二进制模拟进位):

class Solution {
public:
    int getSum(int a, int b) {
    int jie=0;
    int tmp=0;
    for(int i=0;i<32;i++){
        int x=(a>>i)&1;
        int y=(b>>i)&1;
        if(x&&y){
            jie|=tmp<<i;
            tmp=1;
        }else if(x||y){
            jie|=(tmp^1)<<i;
        }else {
            jie|=tmp<<i;
            tmp=0;
            }
    }
    return jie;
    }
};

在这里插入图片描述

解法五:C++,STL模板

class Solution {
public:
    int add(int a, int b) {
    array<int,2>tm{{a,b}};//C++11的标准
    int jie=accumulate(tm.begin(),tm.end(),0);
    return jie;
    }
};

在这里插入图片描述

解法六:卷积(这个是偷看别人的)计科学生含泪翻起了数学系的教材

参考题解
原理:
在这里插入图片描述

typedef unsigned int uint;
class Solution {
public:
	uint plus(uint a,uint b){
		return ((a<<16)|1)*((b<<16)|1)>>16;
	}
	int getSum(int _a,int _b){
		uint a=_a,b=_b,a1=a&0xFFFF,b1=b&0xFFFF,a2=a>>16,b2=b>>16;
		uint c=plus(a2,b2);
		if (b1>(~a1&0xFFFF))c=plus(c,1);
		c=(c<<16)|plus(a1,b1);
		return c;
	}
};

ಥ_ಥ计科落泪

面试题 08.05. 递归乘法

面试题 08.05. 递归乘法
递归乘法。 写一个递归函数,不使用 * 运算符, 实现两个正整数的相乘。可以使用加号、减号、位移,但要吝啬一些。
示例:

 输入:A = 1, B = 10
 输出:10
 输入:A = 3, B = 4
 输出:12

提示:

保证乘法范围不会溢出

解法一:直接用*

class Solution {
public:
    int multiply(int A, int B) {
    return A*B;
    }
};

在这里插入图片描述
解法二:递归(用循环迭代也可以for/while)

class Solution {
public:
    int multiply(int A, int B) {
    B--;
    if(!B)return A;
    return multiply(A,B)+A;
    }
};

在这里插入图片描述
解法三:用二进制来计算

class Solution {
public:
    int multiply(int A, int B) {
        return (B & 1 ? A : 0) + ( B > 1 ? multiply(A + A, B >> 1) : 0);
    }//将B拆成二进制的形式,B&1获得B二进制最后一位
};

29. 两数相除

两数相除
给定两个整数,被除数 dividend 和除数 divisor。将两数相除,要求不使用乘法、除法和 mod 运算符。
返回被除数 dividend 除以除数 divisor 得到的商。
整数除法的结果应当截去(truncate)其小数部分,例如:truncate(8.345) = 8 以及 truncate(-2.7335) = -2

示例

输入: dividend = 10, divisor = 3
输出: 3
解释: 10/3 = truncate(3.33333..) = truncate(3) = 3

示例

输入: dividend = 7, divisor = -3
输出: -2
解释: 7/-3 = truncate(-2.33333..) = -2

提示:

被除数和除数均为 32 位有符号整数。
除数不为 0。
假设我们的环境只能存储 32 位有符号整数,其数值范围是 [2^31,  2^311]。本题中,如果除法结果溢出,则返回 2^311

解法一:卡BUG ,无视题目

class Solution {
public:
    int divide(int dividend, int divisor) {
    long long jie= (long)dividend/(long)divisor;
    if(jie>INT_MAX||jie<INT_MIN)return INT_MAX;//溢出特判
    else return jie;
    }
};

在这里插入图片描述

解法二:(倍增思想,试除)

求a/b,可将a逐次-b,看能减多少次。这里成倍地去减,每次讲减数2,计数器2;

class Solution {
public:
    int divide(int dividend, int divisor) {
    if(divisor==1)return dividend;
    if(divisor==-1){
        if(dividend>INT_MIN)return -dividend;
        else return INT_MAX;
    }//注意对溢出的特判
    bool jd=0;
    if((dividend<0&&divisor>0)||(dividend>0&&divisor<0))jd=1;
    long jie=div(abs(dividend),abs(divisor));
    if(jd)return -jie;
    else {
        if(jie>INT_MAX)return INT_MAX;
        else return jie;
    }
    }
long div(long dividend,long divisor){
    if(dividend<divisor)return 0;
    long cnt=1;
    long tmp=divisor;
    while(dividend>=(tmp<<1)){
        tmp<<=1;
        cnt<<=1;
    }
    return cnt+div(dividend-tmp,divisor);
}
};

在这里插入图片描述

50。Pow(x, n)经典的快速幂模板,我用以前的模板了

class Solution {
public:
typedef long long ll;
double qsmi(double x,int n){
    if(n==0)return 1.00000;
    double jie=qsmi(x,n/2);
    jie*=jie;
    if(n&1) jie=jie*x;
    return jie;
}
    double myPow(double x, int n) {
    return (n>0)?qsmi(x,n):qsmi(1.0/x,n);
    }
};

在这里插入图片描述
69. Sqrt(x)

69. Sqrt(x)

给你一个非负整数 x ,计算并返回 x 的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5) 或者 x ** 0.5 。

解法一:无视题意(面试时不要这么干):

class Solution {
public:
    int mySqrt(int x) {
    return (int)sqrt(x);
    }
};

在这里插入图片描述

解法二:BP枚举

class Solution {
public:
    int mySqrt(int x) {
    long long  jie=0;
    long long mi=100000001;
    for(long long  i=1;i*i<=x;i++){
         long long tmp=x-i*i;
         if(tmp<mi){mi=tmp;jie=i;}
    }
    return jie;
    }
};

面试题 16.07. 最大数值

面试题 16.07. 最大数值

编写一个方法,找出两个数字a和b中最大的那一个。
不得使用if-else或其他比较运算符。
输入: a = 1, b = 2
输出: 2

解法一:

class Solution {
public:
    int maximum(int a, int b) {
    return a>b?a:b;
    }
};

解法二:

class Solution {
public:
    int maximum(int a, int b) {
    return max(a,b);
    }
};

解法三:

class Solution {
public:
    int maximum(int a, int b) {
    array<int,2>tm{{a,b}};
    return *max_element(tm.begin(),tm.end());
    }
};

真。解法四:

class Solution {
//a,b,变为long的c,d
// a < b:
// 1 + (c - d) >> 63 == 0
// a > b:
// 1 + (c - d) >> 63 == 1
public:
    int maximum(int a, int b) {
        long c = a, d = b;
        int k = 1 + ((c - d) >> 63);
        return k * a + (!k) * b;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

0<Solving)1

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值