1、 二进制中1的个数
1.1 题目描述:
请实现一个函数,输入一个整数,输出该数二进制表示中 1 的个数。例如,把 9 表示成二进制是 1001,有 2 位是 1。因此,如果输入 9,则该函数输出 2。
1.2 题解
1.2.1 逐位判断
根据 与运算 定义,设二进制数字 nn,则有: 若 n & 1 = 0,则 n二进制 最右一位 为 0 ; 若 n
& 1 = 1 ,则 n 二进制 最右一位 为 1 。 根据以上特点,考虑以下 循环判断 : 判断 n最右一位是否为
1 ,根据结果计数。 将 n右移一位(本题要求把数字 n 看作无符号数,因此使用 无符号右移 操作)。
public int hammingWeight(int n) {
int res = 0;
while (n!=0){
res+=n&1;
n=n>>>1;
}
return res;
}
1.2.2 巧用 n & (n - 1)
(n - 1) 解析: 二进制数字 n最右边的 1变成 0 ,此 11右边的 0 都变成 1 。
n & (n- 1) 解析: 二进制数字 nn最右边的 1 变成 0,其余不变。
public int hammingWeight(int n) {
int res = 0;
while (n!=0){
n=n&(n-1);
res++;
}
return res;
}
2、数值的整数次方
2.1 题目描述:
实现函数double Power(double base, int exponent),求base的exponent次方。不得使用库函数,同时不需要考虑大数问题。
。
2.2 题解
2.2.1 快速幂解析(二分法角度)
public double myPow(double x, int n) {
if(x == 0) return 0;
long b = n;
double res = 1.0;
if(b < 0) {
x = 1 / x;
b = -b;
}
while(b > 0) {
if((b & 1) == 1) res *= x;
x *= x;
b >>= 1;
}
return res;
}
3、打印从1到最大的n位数
3.1 题目描述:
输入数字 n,按顺序打印出从 1 到最大的 n 位十进制数。比如输入 3,则打印出 1、2、3 一直到最大的 3 位数 999。
3.2 题解
3.2.1
public int[] printNumbers(int n) {
if(n==0)
return new int[]{0};
int i=n;
int len=0;
while(i!=0){ //获取需要存储多少位
len=len*10+9;
i/=10;
}
int[] res=new int[len];
for(int j=0;j<len;j++){//按位输入
res[j]=j+1;
}
return res;
}
3.2.2 考虑大数情况
class Solution {
StringBuilder res;
int count = 0, n;
char[] num, loop = {'0', '1', '2', '3', '4', '5', '6', '7', '8', '9'};
public String printNumbers(int n) {
this.n = n;
res = new StringBuilder(); // 数字字符串集
num = new char[n]; // 定义长度为 n 的字符列表
dfs(0); // 开启全排列递归
res.deleteCharAt(res.length() - 1); // 删除最后多余的逗号
return res.toString(); // 转化为字符串并返回
}
void dfs(int x) {
if(x == n) { // 终止条件:已固定完所有位
res.append(String.valueOf(num) + ","); // 拼接 num 并添加至 res 尾部,使用逗号隔开
return;
}
for(char i : loop) { // 遍历 ‘0‘ - ’9‘
num[x] = i; // 固定第 x 位为 i
dfs(x + 1); // 开启固定第 x + 1 位
}
}
}