1. 题目描述
数据范围
1≤n≤100000,
0≤数列中元素的值≤10^9
2. 解题思路
2.1 暴力法求解
对于暴力解法有对每一位都查看是否是1,然后直接返回结果。通过方法x >> k & 1
来判断k
位是否是1.
import java.io.BufferedInputStream;
import java.util.Scanner;
public class Main{
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int n = sc.nextInt();
while(n-- > 0){
int num = sc.nextInt();
int res = 0;
while(num != 0) {
// 每次看第0位是否为1
res += num & 1;
// 将该数字右移
num = num >> 1;
}
System.out.print(res + " ");
}
}
}
【复杂度分析】
时间复杂度:O(nlogn)
2.2 lowbit方法
lowbit
操作是每次都截取一个数字最后一个1后面的所有位,每次减去lowbit
得到的数字,知道数字减到了0,就得到了最终1的个数。
利用lowbit
,每次都可以去从左到右的第一个1之后的所有位数,减去,记录有多少次就可以的到最终1的个数。
对于lowbit
的求法,可以利用位运算的一些小技巧。计算机负数表示的特点,如一个数字原码是10001000
,他的负数表示形势是补码,就是反码+1
,反码是01110111
,加一则是01111000
,二者按位与得到了1000
,就是我们想要的lowbit
操作.
具体的代码实现如下:
public static int lowbit(int x){
return x & -x;
}
此题代码求解:
import java.io.BufferedInputStream;
import java.util.Scanner;
public class Main {
public static void main(String[] args) {
Scanner sc = new Scanner(new BufferedInputStream(System.in));
int n = sc.nextInt();
while(n-- > 0){
int num = sc.nextInt();
int res = 0;
while(num != 0) {
res ++;
System.out.println(lowbit(num));
num -= lowbit(num);
}
System.out.print(res + " ");
}
}
public static int lowbit(int x){
return x & -x;
}
}
【复杂度】
时间复杂度:O(nlogn)