Leetcode原题
思路
方法一 动态规划
a[i]表示i的二进制中1的个数,那么bits[i-1]就是bits[i]拿掉一个1之后的值,i & (i - 1)就是去掉最低位的一个1。,因此 i & (i - 1)是比 i 小的,而且i & (i - 1)的1的个数已经在前面算过了,所以i的1的个数就是 i & (i - 1)的1的个数加上1
public int[] countBits(int n) { int a[]=new int[n+1]; for (int i=1;i<=n;i++){ a[i] = a[i &(i-1)] +1; } return a; }
方法二 奇偶法
对于所有的数字,只有两类:
奇数:二进制表示中,奇数一定比前面那个偶数多一个 1,因为多的就是最低位的 1。
举例: 0 = 0 1 = 1 2 = 10 3 = 11
偶数:二进制表示中,偶数中 1 的个数一定和除以 2 之后的那个数一样多。因为最低位是 0,除以 2 就是右移一位,也就是把那个 0 抹掉而已,所以 1 的个数是不变的。
举例: 2 = 10 4 = 100 8 = 1000 3 = 11 6 = 110 12 = 1100
另外,0 的 1 个数为 0,于是就可以根据奇偶性开始遍历计算了。
//方法2: 奇偶法 public int[] countBits2(int n) { int a[]=new int[n+1]; a[0] =0; for (int i = 1; i <=n ; i++) { if ((i&1) ==1){ //使用位运算判断奇偶数,等于1是奇数 a[i] = a[i-1]+1; //二进制表示中,奇数一定比前面那个偶数多一个 1,因为多的就是最低位的 1 }else { a[i] =a[i>>1]; //二进制表示中,偶数中 1 的个数一定和除以 2 之后的那个数一样多。因为最低位是 0,除以 2 就是右移一位,也就是把那个 0 抹掉而已,所以 1 的个数是不变的。 } } return a; }
有兴趣的老爷,还可以关注我的公众号【一起收破烂】,回复【006】获取 最新java面试资料以及简历模型120套哦~