面试题 10:二进制中1的个数

标签 :剑指Offer


问题描述:
统计一个整数n的二进制表示中1出现的次数。

考虑:
该整数为0的情况;
该整数为负数的情况;

思路:

  1. 右移法
      将该整数n和1做与操作,如果结果为1,说明最低位是1,如果结果为0,说明最低位为0。循环使整数n右移一位,统计1出现的次数,直到n为0,循环结束。32位整数要循环32次。
    public int NumberOf1(int n){
        int count = 0;
        while(n != 0){
            if(n & 1 == 1) count++;
            n = n >> 1;
        }
        return count;
    }

  因为负数右移时,最高位一直产生1,该解法遇到负数时会死循环。

  1. 左移法
      左移法能解决负数问题。思路是使用一个临时变量,从1开始,一直左移,并和n做与操作。如果结果不为0,说明当前位是1,如果结果为0,说明当前位是0。直到临时变量为0,循环结束。32位整数要循环32次。
    public int NumberOf1(int n){
        int count = 0;
        int flag = 1;
        while(flag != 0){
            if(n & flag != 0) count++;
            flag = flag << 1;
        }
        return count;
    }
  1. 特殊法
      一个整数与自身减1做与操作,能消去该整数的最右边的一个1。这条规则对于所有整数都适用。整数有几个1,循环就执行几次。
    public int NumberOf1(int n){
        int count = 0;
        while(n != 0){
            count++;
            n = n & (n - 1);
        }
        return count;
    }

题目变形:二进制中0的个数

  1. 用32减去1的个数。
  2. 一个整数和自身加1做或操作,能把最右边的0变成1。一直循环判断,直到n+1为0,循环结束。
posted @ 2017-04-14 22:35  斑鱼  阅读(155)  评论(0编辑  收藏  举报