一、
难度简单108收藏分享切换为英文接收动态反馈
编写一个方法,找出两个数字a
和b
中最大的那一个。不得使用if-else或其他比较运算符。
示例:
输入: a = 1, b = 2 输出: 2
class Solution {
public:
int maximum(int a, int b) {
int la=sizeof(a)*8;
int aa=static_cast<unsigned>(a)>>(la-1);
int bb=static_cast<unsigned>(b)>>(la-1);
int k=aa^1;
int tmp=(aa^bb^1)&&(k=(static_cast<unsigned>(a-b)>>(la-1))^1);
return a*k+b*(k^1);
}
};
学习到的知识:
1.static_cast<unsigned>(a)表示将a转化为‘+’符号型,使其右移时符号位统一补0;
2.int tmp=(aa^bb^1)&&(k=(static_cast<unsigned>(a-b)>>(la-1))^1);当aa^^bb^1为0时,由于程序的短路性会不执行后面的操作,则k=aa^1;
3.若a为正,b为负,k=aa^1=1,不执行k=(static_cast<unsigned>(a-b)>>(la-1))^1,return结果为a;类推;
------------------------------------------------------------------------------------------------------------------------------
二、
难度简单912
给你一个非负整数 x
,计算并返回 x
的 算术平方根 。
由于返回类型是整数,结果只保留 整数部分 ,小数部分将被 舍去 。
注意:不允许使用任何内置指数函数和算符,例如 pow(x, 0.5)
或者 x ** 0.5
。
示例 1:
输入:x = 4 输出:2
示例 2:
输入:x = 8 输出:2 解释:8 的算术平方根是 2.82842..., 由于返回类型是整数,小数部分将被舍去。
我的方法:使用递归
class Solution {
public:
int mysolve(int start,int end,int target){
if(end-start==1){
return start;
}
long mid=(start+end)/2;
if(mid*mid==target){
return mid;
}
if(mid*mid>target){
return mysolve(start,mid,target);
}
else if(mid*mid<target){
return mysolve(mid,end,target);
}
return 1;
}
int mySqrt(int x) {
long result=1;
while(result*result<=x){
result*=2;
}
int ret=result/2;
int target=mysolve(ret,result,x);
return target;
}
};
***************************************其他人好的方法:牛顿迭代法************************************
class Solution {
public:
int s;
int mySqrt(int x) {
s=x;
if(x==0)
{
return 0;
}
return (int)mysolve(x);
}
double mysolve(double x){
double ret=((x+s/x)/2);
if(ret==x)
{
return x;
}
return mysolve(ret);
}
};
例如,我想求根号 2 等于多少。假如我猜测的结果为 4,虽然错的离谱,但你可以看到使用牛顿迭代法后这个值很快就趋近于根号 2 了:
( 4 + 2/ 4 ) / 2 = 2.25
( 2.25 + 2/ 2.25 ) / 2 = 1.56944..
( 1.56944..+ 2/1.56944..) / 2 = 1.42189..
( 1.42189..+ 2/1.42189..) / 2 = 1.41423..
ret=(估计数+被开方数/估计数)/2
------------------------------------------------------------------------------------------------------------------------------
三、
难度简单464
给你一个整数 n
,请你判断该整数是否是 2 的幂次方。如果是,返回 true
;否则,返回 false
。
如果存在一个整数 x
使得 n == 2x
,则认为 n
是 2 的幂次方。
我的递归做法:
class Solution {
public:
bool isPowerOfTwo(int n) {
if(n==1)
{
return true;
}
if(n%2==1||n==0)return false;
return isPowerOfTwo(n/2);
}
};
使用位运算:
2^x n n - 1 n & (n - 1)
2^0 0001 0000 (0001) & (0000) == 0
2^1 0010 0001 (0010) & (0001) == 0
2^2 0100 0011 (0100) & (0011) == 0
2^3 1000 0111 (1000) & (0111) == 0
class Solution {
public:
bool isPowerOfTwo(int n) {
if(n>0&&(n&(n-1))==0){
return true;
}
return false;
}
};
若n为2的幂数:n&(n-1)=0
------------------------------------------------------------------------------------------------------------------------------
四、
难度简单245
给定一个整数,写一个函数来判断它是否是 3 的幂次方。如果是,返回 true
;否则,返回 false
。
整数 n
是 3 的幂次方需满足:存在整数 x
使得 n == 3^x
我的暴力解法直接跳过;
接下来讲述倍数约数解法:
class Solution {
public:
bool isPowerOfThree(int n) {
return n>0&&1162261467%n==0;
}
};
首先1162261467这个数字怎么来?
3^19次方=1162261467,假设一个n为3的幂数,则必满足n*3^k==1162261467,即1162261467/n=3^k,1162261467%3==0;
时间复杂度为O(1)
------------------------------------------------------------------------------------------------------------------------------
五、
难度简单289
给定一个整数,写一个函数来判断它是否是 4 的幂次方。如果是,返回 true
;否则,返回 false
。
整数 n
是 4 的幂次方需满足:存在整数 x
使得 n == 4x
示例 1:
输入:n = 16 输出:true
示例 2:
输入:n = 5 输出:false
示例 3:
输入:n = 1 输出:true
提示:
-231 <= n <= 231 - 1
不使用递归和循环
第一种解法:
class Solution {
public:
bool isPowerOfFour(int n) {
return n > 0 && (n & (n - 1)) == 0 && (n & (-n)) == 0;
}
};
因为4的幂数为可以表示为2^0+2^2+2^4+......,二进制表达为积位数上是1,偶位数上为0,则可知n和-n的二进制表达相同,则n&-n=n,再加上中间n&(n-1)确认其为2的幂数,可知n是否为4的倍数;
第二种解法:
class Solution {
public:
bool isPowerOfFour(int n) {
return n > 0 && (n & (n - 1)) == 0 && n % 3 == 1;
}
};
先确定为2的幂数,