剑指offer-第十题方法总结

Posted 午饭要阳光

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了剑指offer-第十题方法总结相关的知识,希望对你有一定的参考价值。

题目:实现一个函数,输入一个整数,请输出这个数的二进制表示中1的个数。例如:输入5,的二进制是101,有两个1则输出2.

这个题目很简单啊!!!
int count_one(int n)
{
                 int count = 0;
                 while (n)
                {
                                 if (n&1)
                                count++;
                                n=n >> 1;
                }
                 return count;
}


     写出上面的代码是有问题的,如果输入负数,则进行的是算术移位,就会陷入死循环。


     略微思考一下可以将上面这种方法改进一下,整数有32个bit位,分别将这个数的每一位与1按位与,如果为真,则count++。
int count_one(int n)
{
                 int i = 0;
                 int count = 0;
                 for (i = 0; i < 32; i++)
                {
                                count += (( n >>i) & 1);
                }
                 return count;
}

    这样确实能够做出来,对于每一个数,都要判断32次,很麻烦。


      那么有没有一种方法能够使得一个数二进制中有多少个1, 就循环多少次呢???
       答案是有的。

先看看下面这些式子找一找规律:
 1、
10    &    9      =8
1010       1001 =1000

2、
 8     &  7        =0
1000      0111 =0000

3、
 5    &   4    =4
101      100 =100

4、
 4     & 3      =0
100      011  =000

可以发现,n&(n-1)的结果与n相比,其二进制中1的个数少了一个。

根据这样的规律我们可以很容易的实现这道题目的最优解。

int count_one(int n)
{
	int count = 0;
	while (n)
	{
		n = n&(n - 1);
		count++;
	}
	return count;
}


以上是关于剑指offer-第十题方法总结的主要内容,如果未能解决你的问题,请参考以下文章

《剑指offer》第五十题I:字符串中第一个只出现一次的字符

《剑指offer》第五十题II:字符流中第一个只出现一次的字符

剑指offer第十一题:二进制中1的个数

剑指Offer(Java版)第四十题:在数组中的两个数字,如果前面一个数字大于后面的数字, 则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数P。 并将P对1000000007取模

剑指Offer(Java版)第十五题:打印1到最大的n位数

剑指Offer(Java版)第十一题