【Offer】[15] 【二进制中1的个数】

  • 题目描述
  • 思路分析
  • 测试用例
  • 代码链接

题目描述

  输入一个整数,输出该数二进制表示中1的个数。其中负数用补码表示。

思路分析

  1. 让整数和1相与,可以判断整数二进制表示中最右边一位是否为1,将1左移之后再和整数相与,可以比较右数第二位,循环比较,就可以统计出二进制中1的个数
    (可能一般想到的是将整数右移,之后再和1相与,但是这种方法传入负数时会陷入死循环,因为负数的右移操作会在高位补1,而不是0
  2. 一个整数减去1之后再和原来的整数相与,那么整数二进制中最右边的1会变为0,直到整数变为0,就可以统计出1的个数。

测试用例

  1. 正数(包括边界值1、0x7FFFFFFF)
  2. 负数(包括边界值0x80000000、0xFFFFFFFF)
  3. 0
      
    ## Java代码
public class Offer15 {
    public static void main(String[] args) {
        System.out.println("测试正数-->");
        test1();
        System.out.println("测试负数-->");
        test2();
        System.out.println("测试0-->");
        test3();
    }
    public static int NumberOf1(int n) {
        return Solution3(n);
    }
    /**
     * 解法一: 思路: 上面的思路是移动 整数,我们可以移动与整数相与的1 ,每次判断之后我们将1 向左移动, 这时判断的就是整数所表示二进制中右边的第二位
     *
     * @param n
     * @return
     */
    private static int Solution2(int n) {
        int count = 0;
        int flag = 1;
        while (flag != 0) {
            if ((flag & n) != 0) {
                count++;
            }
            flag = flag << 1;
        }
        return count;
    }

    /**
     * 解法二: 思路 :利用了一种二进制运算的规律,把一个整数减去1之后再和原来的整数做与运算, 得到的结果相当于把整数二进制中最右边的1变为0
     *
     * @param n
     * @return
     */
    private static int Solution3(int n) {
        int count = 0;
        while (n != 0) {
            count++;
            n = n & (n - 1);
        }
        return count;
    }

    /**
     * 测试正数
     */
    private static void test1() {
        System.out.println("0x7FFFFFFF: " + NumberOf1(0x7FFFFFFF));
        System.out.println("1: " + NumberOf1(1));
    }

    /**
     * 测试负数
     */
    private static void test2() {
        System.out.println("0x80000000: " + NumberOf1(0x80000000));
        System.out.println("0xFFFFFFFF: " + NumberOf1(0xFFFFFFFF));
    }

    /**
     * 测试0
     */
    private static void test3() {
        System.out.println("0: " + NumberOf1(0));
    }
}

代码链接

剑指Offer代码-Java

原文地址:https://www.cnblogs.com/haoworld/p/boffer15-er-jin-zhi-zhong1de-ge-shu.html

时间: 2024-10-13 03:07:35

【Offer】[15] 【二进制中1的个数】的相关文章

【剑指offer】二进制中1的个数

题目描述: 请实现一个函数,输入一个整数,输出该数二进制表示中1的个数.例如把9表示成二进制是1001,有2位是1.因此如果输入9,该函数输出2. 分析描述: 1.对一个整数的二进制形式,要想知道其中1的个数,首先想到的应该就是遍历整个二进制数,用到的方法当然就是移动了(包含左移或右移).例如,用1来跟给定的整数做与运算.如果结果为1,则证明整数的二进制形式中,最右边的一位是1,如果结果是0,则证明整数的二进制形式中,最右边的一位是0. int NumberOf1(int n) { int co

剑指offer (10) 二进制中1的个数

题目:输入一个整数,输出该数二进制表示中1的个数. 我们可能很快写下如下代码: 1 int NumOf1InBinary(int n) 2 { 3 int count = 0; 4 while (n != 0) { 5 if (n & 1 ) { 6 ++count; 7 } 8 n >> 1; // bug!!! 9 } 10 return count; 11 } 第8行存在bug. 首先C/C++中数有无符号数和有符号数两种(我一直认为无符号数是个蛋疼的存在,滋生大量的bug) 左

剑指Offer:二进制中1的个数

题目:输入一个整数,输出该数二进制表示中1的个数. // 二进制中1的个数 #include <stdio.h> int wrong_count_1_bits(int n) // 错误解法: 当n为负数时, n>>=1右移, 最高位补1, 陷入死循环 { int count = 0; while(n) { if( n & 1 ) ++count; n >>= 1; } return count; } int count_1_bits(int n) // 常规解法

《剑指offer》 二进制中1的个数

本题来自<剑指offer> 二进制中1的个数 题目: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路: 两种思路: 第一种:对n进行左移,检测最后一位是否为1,但考虑负数,一直左移会陷入到死循环中. 第二种:对n的每一位进行检测,采用滑标flag,左移,int会是32位,所以会最多移动32次. C++ code1:(第二种思路) class Solution { public: int NumberOf1(int n) { //最多可以移动32次, int count=

[剑指Offer]12.二进制中1的个数

题目 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路 把一个整数减去1,再和原整数做与运算,会把整数最右边一个1变成0.那么一个整数的二进制表示中有多少个1,就可以进行多次这样的操作. 代码 /*--------------------------------------- * 日期:2015-07-20 * 作者:SJF0115 * 题目: 12.二进制中1的个数 * 结果:AC * 网址:http://www.nowcoder.com/books/coding-int

(剑指Offer)------二进制中1的个数

题目: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 思路: 此问题最精彩之处,在于采用---位运算---处理相应的内容 function calNum(){ // var calStr = parseInt(document.getElementById("preArr").value); var calStr =99; var calStrs = parseInt(document.getElementById("preArr").value

剑指Offer之二进制中1的个数

思路分析: 首先分析把一个数减去1的情况,如果一个整数不等于0,那么改整数的二进制表示其中至少有一位是1.先假设这个数的最右边是1,那么减去1时,最后一位变成0而其他所有位都保持不变.也就是最后一位相当于做了取反操作,由1变成了0. 接下来假设最后一位不是1而是0的情况.如果该整数的二进制表示中最右边1位位于第m位,那么减去1时,第m位由1变成0,而第m位之后的所有0都变成1,整数中第m位之前的所有位都保持不变.举个例子:一个二进制数1100,它的第二位是从最右边数起的一个1.减去1之后,第二位

【剑指Offer】二进制中1的个数(位运算)

问题描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 算法分析 本题需要用到位运算 当传进来一个正整数n时,假设n=3,二进制表示为 011 011&1 = 1 一个1, n右移1位 01&1 = 1 又一个1, n右移1位 共需移31次 传进来一个负整数n,假设n = -2 二进制表示为 原码:10000000 00000000 00000000 00000010 反码:11111111 11111111 11111111 11111101 补码:11111111

剑指OFFER之二进制中1的个数(九度OJ1513)

题目描述: 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 输入: 输入可能包含多个测试样例.对于每个输入文件,第一行输入一个整数T,代表测试样例的数量.对于每个测试样例输入为一个整数..n保证是int范围内的一个整数. 输出: 对应每个测试案例,输出一个整数,代表输入的那个数中1的个数. 样例输入: 3 4 5 -1 样例输出: 1 2 32 解题思路: 首先对一个数判断1的个数,可以考虑直接遍历每一位就行了,那么实现起来,可以只看最后一位(与1进行与操作),再进行右移1位.

剑指Offer 11. 二进制中1的个数 (其他)

题目描述 输入一个整数,输出该数二进制表示中1的个数.其中负数用补码表示. 题目地址 https://www.nowcoder.com/practice/8ee967e43c2c4ec193b040ea7fbb10b8?tpId=13&tqId=11164&tPage=1&rp=3&ru=%2Fta%2Fcoding-interviews&qru=%2Fta%2Fcoding-interviews%2Fquestion-ranking 思路 思路1: 从右往左逐位判