LeetCode-338. Counting Bits

LeetCode-338. Counting Bits

  • 题目描述:https://leetcode.com/problems/counting-bits/

解题思路

  • 当然,如果逐位取模再判断是不是1来计算1的个数当然可以,但这样时间复杂度就是O(n*sizeof(integer)) 了,我们想要O(n) 就好。
  • 所以,在于对给定的数num ,我们对区间0 ≤ i ≤ num中的每个数求1 的个数的时间复杂度都要为O(1)
  • 要用到位操作来计算:一个int 为32位,先两两一组相加,之后四个四个一组相加,接着八个八个,最后就得到各位之和了,例如:对于一个8位整数122,用二进制表达是0111 1010 ,相加的过程如果:
    LeetCode-338. Counting Bits_第1张图片

算法描述

  • 这里一个重点难点就是怎样计算每两位,每4位,每8位,每16位,每32位中的1 的个数,用到了移位和与的操作,看下面的代码实现就清楚了。

代码实现-Go

  • Java版-JDK的Integer.bitCount源码:
func countBits(num int) []int {
	var arr []int
	var temp int
	for i := 0; i <= num; i++ {
		temp = countB(i)
		arr = append(arr,temp)
	}
	return arr
}

func countB(num int) int {
	num = (num & 0x55555555) + ((num >> 1) & 0x55555555)
	num = (num & 0x33333333) + ((num >> 2) & 0x33333333)
	num = (num & 0x0f0f0f0f) + ((num >> 4) & 0x0f0f0f0f)
	num = (num & 0x00ff00ff) + ((num >> 8) & 0x00ff00ff)
	num = (num & 0x0000ffff) + ((num >> 16) & 0x0000ffff)
	return num
}

运行结果性能数据:

Runtime864 ms, faster than 44.19% of Go online submissions for Counting Bits.
Memory Usage : 8.1 MB, less than 100.00% of Go online submissions for Counting Bits.

计算二进制中1的个数其它博客介绍推荐:

  • https://www.cnblogs.com/graphics/archive/2010/06/21/1752421.html
  • http://www.cppblog.com/zenliang/articles/131761.html
  • https://www.jianshu.com/p/95dae66c8706

你可能感兴趣的:(LeetCode编程,二进制中1的个数)