191. 位1的个数(位与)
编写一个函数,输入是一个无符号整数n
(以二进制串的形式),返回其二进制表达式中数字位数为 '1'
的个数(也被称为汉明重量)。
思路:
- 输入是一个无符号整数的
32位二进制串n
- 循环
32
次,每次都将n
与1
进行位与运算(相当于比较n
的最低位),可以查看当前n
的最低位是不是1
,是1
的话计数器加一。 - 每次循环都将
n
向右移一位。
代码
class Solution {
public:
int hammingWeight(uint32_t n) {
int ret = 0;
for(int i=0;i<32;i++)
{
if(n&1!=0) ret++;
n>>=1;
}
return ret;
}
};
461. 汉明距离(异或)
两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目。
给出两个整数x
和y
,计算它们之间的汉明距离。
注意:
0 ≤ x, y < 2^31.
思路:
- 利用异或运算,相同的两数进行异或运算,结果为
0
,不同的话结果为1
- 对经过异或运算的结果中的
1
计数,就可以得到两数二进制位不同的位置的数目。
代码
class Solution {
public:
int hammingDistance(int x, int y) {
//先异或(相同值的异或结果为0),再看结果中有多少个1
int z=x^y;
int result=0;
//数1
for(int i=0;i<32;i++)
{
//逐个看最低位是否为1
if(z&1!=0) result++;
//右移,左边由0填充
z=z>>1;
}
return result;
}
};
190. 颠倒二进制位(左/右移+位或/与)
颠倒给定的 32 位无符号整数的二进制位。
思路(官方题解)
- 将
n
视作一个长为32
的二进制串,从低位往高位枚举n
的每一位,将其倒序添加到翻转结果result
中。 - 代码实现中,每枚举一位就将
n
右移一位,这样当前 n 的最低位就是我们要枚举的比特位。当n
为0
时即可结束循环。
代码
class Solution {
public:
uint32_t reverseBits(uint32_t n) {
uint32_t rev = 0;
for (int i = 0; i < 32 && n > 0; ++i) {
rev |= (n & 1) << (31 - i);
n >>= 1;
}
return rev;
}
};
20. 有效的括号(栈)
给定一个只包括 '('
,')'
,'{'
,'}'
,'['
,']'
的字符串 s
,判断字符串是否有效。
有效字符串需满足:
- 左括号必须用相同类型的右括号闭合。
- 左括号必须以正确的顺序闭合。
思路: - 利用栈,如果读入左括号,就将其入栈
- 如果读入右括号,先看栈中是否有括号,没有的话返回
false
,有的话就弹出栈顶元素,看是否和当前的右括号匹配 - 不匹配的话就可以返回
false
了 - 遍历完整个字符串后如果栈中还存在括号也要返回
false
,因为这说明有未匹配成功的括号
代码
class Solution {
public:
bool isValid(string s) {
/*利用栈,如果读入左括号,就将其入栈
如果读入右括号,就弹出栈顶元素,看是否和当前的右括号匹配
不匹配的话就可以返回false了*/
//长度为奇数直接返回`false`
if(s.length()%2!=0) return false;
//左括号栈
stack<char>st;
for(int i=0;i<s.length();i++)
{
switch(s[i]){
case '(': st.push(s[i]);break;
case '[': st.push(s[i]);break;
case '{': st.push(s[i]);break;
case ')':
if(st.empty()) return false;
if(st.top()=='(') st.pop();
else return false;
break;
case ']':
if(st.empty()) return false;
if(st.top()=='[') st.pop();
else return false;
break;
case '}':
if(st.empty()) return false;
if(st.top()=='{') st.pop();
else return false;
break;
}
}
if(!st.empty()) return false;
return true;
}
};