LeetCode Java刷题笔记—338. 比特位计数

338. 比特位计数

给你一个整数 n ,对于 0 <= i <= n 中的每个 i ,计算其二进制表示中 1 的个数 ,返回一个长度为 n + 1 的数组 ans 作为答案。

简单难度。这道题我们可以对每一个数循环进行191. 位1的个数的元算即可。

public int[] countBits( int n ){

   int[] res = new int[ n + 1 ];
   for( int i = 0; i <= n; i++ ){
      res[ i ] = count( i );
   }
   return res;
}

/**
 * 对每一位的二进制1数进行统计
 */
private int count( int i ){

   int sum = 0;
   while( i != 0 ){
      sum++;
      sum &= ( sum - 1 );
   }
   return sum;
}

但是这样做会超出时间限制,我们需要在线性时间复杂度 O(n) 内用一趟扫描解决此问题。

我们知道i >> 1运算是将i的二进制数向右右移一位,因此会把最低位去掉,高位补0,结果会比i更小。当 i 的最低位是0,那么i和i >> 1中1的个数相同;当i的最低位是1,那么i的个数是 i >> 1的1的个数加1。我们可以知道,0的1二进制表示中 1 的个数为0,1的二进制表示中 1 的个数为1。

利用此规律,我们可以利用数组前面已经算好的数来计算当前数的1的个数,这里用到了动态规划。

/**
 * 利用数组前面已经算好的数来计算当前数的1的个数
 */
public int[] countBits( int n ){

   int[] res = new int[ n + 1 ];
   for( int i = 0; i <= n; i++ ){
      //当前数的结果是它的i >> 1的结果,可能需要加1,通过i & 1获取低位的值相加即可
      res[ i ] = res[ i >> 1 ] + ( i & 1 );
   }
   return res;
}
  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

刘Java

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值