想必大家对位运算并不陌生了,这边就不做过多的描述.我还是直接单刀直入
LeetCode191:编写一个函数,输入一个无符号的整数,然后返回的是这个无符号整数的二进制里面有多少个1的存在.
分析:我们可以要明确的一点是 只要是和二进制有关的都是和二进制有关系.就入下面的例子一样 既然要计算的是 1的个数有多少个 那我们就可以想到用这个数和1进行做文章 根据我们学到的 那就是& 操作 并且我们只要一个二进制位进行有32位 . 为什么呢 因为&是只有两个为 1 的才会变成1. 有0出0 的操作 所以我们就可以很快的想到.
示例 1:
输入:n = 00000000000000000000000000001011
输出:3
解释:输入的二进制串 00000000000000000000000000001011 中,共有三位为 '1'。
那我们直接来看代码吧:
public class Solution {
// you need to treat n as an unsigned value
public int hammingWeight(int n) {
//定义一个变量 cout 用来记录 有几个1出现
int count = 0;
//采用&来进行计算有几个1
for(int i = 0;i<32;i++){
cout +=(n>>1)&1;
}
return count;
}
}
LeetCode338:给你一个整数 n
,对于 0 <= i <= n
中的每个 i
,计算其二进制表示中 1
的个数 ,返回一个长度为 n + 1
的数组 ans
作为答案。
示例 1:
输入:n = 2 输出:[0,1,1] 解释: 0 --> 0 1 --> 1 2 --> 10
分析:根据题目的意思我们可以知道的是 还是要算1的个数 只是不一样的是 他不是算一个数1的个数 而是算0-该数这些数 的1的个数. 很简单的方法
class Solution {
public int[] countBits(int n) {
int count = 0;
int[] arr = new int[n+1];
for (int i = 0; i <= n; i++) {
for (int j = 0; j < 32; j++) {
//通过不断右移来确定有几个1
arr[i] += (i >> j)&1;
}
}
return arr;
}
}
LeetCode190:颠倒给定的32位的无符号整数的二进制.
示例 1:
输入:n = 00000010100101000001111010011100 输出:964176192 (00111001011110000010100101000000) 解释:输入的二进制串 00000010100101000001111010011100 表示无符号整数 43261596, 因此返回 964176192,其二进制表示形式为 00111001011110000010100101000000。
分析:这边给定的是一个无符号的整数 那么我们就可以知道的是 这个数不是一个负数的形式. 既然不是负数 那么我们就可以知道的是 这个整数的最高为的1不是代表符号.举个例子就是下面 并且在做这道题的是时候还有一个很关键的关键点 我们可以发现的是 下面的例子都是让高位变成0的操作 所以要想这样子的操作就是要采用的是逻辑右移的操作.
思路:我们可以观察上面的例子发现 我们对输入的n的最后一位数字最终要通过我们的移动到res(结果的第一位置上去) 那么我们就要将其进行右移动(因为n进行右移动的话 就可以n的最低位进行抛弃 将res进行左移操作 左移操作 就可以让res的左边进行补上 简单的理解就是把 n的低位的数字 给到 res的高位 从而达成到 颠倒的想法 ) 大体的做法是这样子的 并且 要注意点是左移右移都是用0来进行补位 所以我们不需要考虑 0的可能 只需要考虑 若我把n的抛弃的低位是1的话 我们就需要把这个1加到res的高位上去.这样子就可以完成了
大致的窜一下 我们要判断是否有1在的话 就要使用&符号来进行操作 要抛弃低位的话 就要用到右移操作 ,要补高位的话 就要进行左移操作.那么直接看代码
public class Solution {
// you need treat n as an unsigned value
public int reverseBits(int n) {
int res = 0;
for (int i = 0; i < 32; i++) {
//将res向右移一位
res <<=1;
if((n&1)==1){
res +=1;
}
n >>=1;
}
return res;
}
}
LeetCode371:给你两个整数 a
和 b
,不使用 运算符 +
和 -
,计算并返回两整数之和。
示例 1:
输入:a = 1, b = 2 输出:3
示例 2:
输入:a = 2, b = 3 输出:5
分析:既然是不可以使用+和-符号的话 那么我们只能进行使用位运算来进行操作.如果把两个数分别当成1和0,那^的结果跟+号是等价的,区别在于+号多一个进位,这里相当于先把进位的值算出来,然后下次循环给加上
class Solution {
public int getSum(int a, int b) {
while (b!=0){
//判断是否有进位操作
int count = (a&b)<<1;
a = a^b;
b = count;
}
return a;
}
}
其实a^b就是同等于 + 号一样 只是他无法进行进位操作 所以 我们需要单独使用count来记录是否要进行进位操作.