题目目录:
- 371.两整数之和】面试题 17.01. 不用加号的加法】剑指 Offer 65. 不用加减乘除做加法
- 解法一:直接用‘+’,‘-’;
- 解法二(对数运算法):
- 解法三:位运算法:
- 解法四(二进制模拟进位):
- 解法五:C++,STL模板
- 解法六:卷积(这个是偷看别人的)计科学生含泪翻起了数学系的教材
- 面试题 08.05. 递归乘法
- 解法一:直接用*
- 在这里插入图片描述 解法二:递归(用循环迭代也可以for/while)
- 在这里插入图片描述 解法三:用二进制来计算
- 29. 两数相除
- 解法一:卡BUG ,无视题目
- 解法二:(倍增思想,试除)
- 50。Pow(x, n)经典的快速幂模板,我用以前的模板了
- 在这里插入图片描述 69. Sqrt(x)
- 解法一:无视题意(面试时不要这么干):
- 解法二:BP枚举
- 面试题 16.07. 最大数值
- 解法一:
- 解法二:
- 解法三:
- 真。解法四:
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^31 − 1]。本题中,如果除法结果溢出,则返回 2^31 − 1。
解法一:卡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)
给你一个非负整数 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. 最大数值
编写一个方法,找出两个数字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;
}
};