可能会引起死循环的解法:
看最右边一位是不是1,然后将输入的整数右移一位,再判断最右边一位(即倒数第二位)是否为1,接着再右移,知道整数移动到0为止
这个解法,把整数右移一位和把整数除以2在数学上是等价的,但是不能换成除以2,因为除法的效率要比移位运算要低得多,实际编程中,尽可能用移位运算代替乘除法。
但是这个解法存在的问题是,输入一个负数,负数0x80000000右移一位的时候,并不是简单的把最高位的1移到第二位变成0x40000000,而是0xC00000000,因为移位前是一个负数,仍然要保证移位后是一个负数,因此移位后的最高位会设置为1,如果一直右移运算,那么最终这个数字就会变成0xFFFFFFFF而陷入死循环。
class Solution {
public:
int hammingWeight(uint32_t n) {
int result=0;
while(n)
{
if(n&1) result++;//判断最右边一位是否为1
n=n>>1; //n右移一位
}
return result;
}
};
常规解法:不引起死循环,就不能右移整数n。首先n和1做位运算,判断倒数第一位是否为1,然后1右移变成2即10,做位运算,判断倒数第二位是否为1,接着2再右移一位变成4即100,判断倒数第三位是否为1.
循环的次数:整数二进制的位数,32位的整数需要循环32次,f定义为unsigned int ,因此while(f) 循环32次,同时题目中输入也必须是长度为32的二进制串
class Solution {
public:
int hammingWeight(uint32_t n) {
int result=0;
unsigned int f=1;
while(f)
{
if(n&f) result++;//每次判断当前f在的1的位置是否为1
f=f<<1; //f左移一位
}
return result;
}
};
把一个整数减去1,在和原整数进行位运算,会把该证书最右边的1变成0,有多少个1,进行多少次该操作
class Solution {
public:
//复杂度logn
int hammingWeight(uint32_t n) {
int result=0;
while(n)
{
n&=n-1;
result++;
}
return result;
}
};
class Solution {
public:
bool isBalanced(TreeNode* root) {
return height(root)!=-1;
}
private:
int height(TreeNode* root)
{
if(!root) return 0;
int left_dep=height(root->left);
int right_dep=height(root->right);
if(abs(left_dep-right_dep)>1||left_dep==-1||right_dep==-1) return -1;
return max(left_dep,right_dep)+1;
}
};
数组的整数次方
class Solution {
public:
double myPow(double x, int n) {
double result=1;
int flag=n>0?1:0;
long long N=abs(n);
while(N)
{
if(N&1) result*=x;
x=x*x;
N=N>>1;
}
if(flag==0) result=1/result;
return result;
}
};
超过一半的次数
class Solution {
public:
int majorityElement(vector<int>& nums) {
unordered_map<int,int> mp;
int len=nums.size();
for(int i=0;i<nums.size();i++)
{
mp[nums[i]]++;
if(mp[nums[i]]>len/2) return nums[i];
}
return 1;
}
};