面试算法3:前n个数字二进制形式中1的个数

2023-09-15 10:30:09

题目

输入一个非负数n,请计算0到n之间每个数字的二进制形式中1的个数,并输出一个数组。例如,输入的n为4,由于0、1、2、3、4的二进制形式中1的个数分别为0、1、1、2、1,因此输出数组[0,1,1,2,1]。

分析1

很多人在面试的时候都能想到直观的解法,使用一个for循环来计算从0到n的每个整数i的二进制形式中1的个数。于是问题转换成如何求一个整数i的二进制形式中1的个数。
计算整数i的二进制形式中1的个数有多种不同的方法,其中一种比较高效的方法是每次用“i&(i-1)”将整数i的最右边的1变成0。整数i减去1,那么它最右边的1变成0。如果它的右边还有0,则右边所有的0都变成1,而其左边所有位都保持不变。下面对i和i-1进行位与运算,相当于将其最右边的1变成0。以二进制的1100为例,它减去1的结果是1011。1100和1011的位与运算的结果正好是1000。二进制的1100最右边的1变为0,结果刚好就是1000。

解1

public class Test {
    public static void main(String[] args) {
        int[] result = countBits(4);
        for (int res : result) {
            System.out.println(res);
        }
    }

    public static int[] countBits(int num) {
        int[] result = new int[num + 1];
        for (int i = 0; i <= num; i++) {
            int j = i;
            while (j != 0) {
                result[i]++;
                j = j & (j - 1);
            }
        }
        return result;
    }
}

分析2

根据前面的分析可知,“i&(i-1)”将i的二进制形式中最右边的1变成0,也就是说,整数i的二进制形式中1的个数比“i&(i-1)”的二进制形式中1的个数多1。

解2

public class Test {
    public static void main(String[] args) {
        int[] result = countBits(4);
        for (int res : result) {
            System.out.println(res);
        }
    }

    public static int[] countBits(int num) {
        int[] result = new int[num + 1];
        for (int i = 1; i <= num; i++) {
            result[i] = result[i & (i - 1)] + 1;
        }

        return result;
    }
}

分析3

还可以使用另一种思路来解决这个问题。如果正整数i是一个偶数,那么i相当于将“i/2”左移一位的结果,因此偶数i和“i/2”的二进制形式中1的个数是相同的。如果i是奇数,那么i相当于将“i/2”左移一位之后再将最右边一位设为1的结果,因此奇数i的二进制形式中1的个数比“i/2”的1的个数多1。例如,整数3的二进制形式是11,有2个1。偶数6的二进制形式是110,有2个1。奇数7的二进制形式是111,有3个1。我们可以根据3的二进制形式中1的个数直接求出6和7的二进制形式中1的个数。

解3

public class Test {
    public static void main(String[] args) {
        int[] result = countBits(4);
        for (int res : result) {
            System.out.println(res);
        }
    }

    public static int[] countBits(int num) {
        int[] result = new int[num + 1];
        for (int i = 1; i <= num; i++) {
        	// 用“i>>1”计算“i/2”,用“i&1”计算“i%2”
            result[i] = result[i >> 1] + (i & 1);
        }

        return result;
    }
}
更多推荐

C++ 指针

C++指针学习C++的指针既简单又有趣。通过指针,可以简化一些C++编程任务的执行,还有一些任务,如动态内存分配,没有指针是无法执行的。所以,想要成为一名优秀的C++程序员,学习指针是很有必要的。正如您所知道的,每一个变量都有一个内存位置,每一个内存位置都定义了可使用连字号(&)运算符访问的地址,它表示了在内存中的一个

网络安全(黑客)自学

前言我是去年8月22日才正式学习网络安全的,因为在国营单位工作了4年,在广东一个月工资只有5000块,而且看不到任何晋升的希望,如果想要往上走,那背后就一定要有关系才行。而且国营单位的气氛是你干的多了,领导觉得你有野心,你干的不多,领导却觉得你这个人不错。我才24周岁,实在的受不了这种工作氛围,情绪已经压制了很多久,一

竞赛选题 基于深度学习的人脸表情识别

文章目录0前言1技术介绍1.1技术概括1.2目前表情识别实现技术2实现效果3深度学习表情识别实现过程3.1网络架构3.2数据3.3实现流程3.4部分实现代码4最后0前言🔥优质竞赛项目系列,今天要分享的是基于深度学习的人脸表情识别该项目较为新颖,适合作为竞赛课题方向,学长非常推荐!🧿更多资料,项目分享:https:/

java版Spring Cloud+Mybatis+Oauth2+分布式+微服务+实现工程管理系统

鸿鹄工程项目管理系统SpringCloud+SpringBoot+Mybatis+Vue+ElementUI+前后端分离构建工程项目管理系统1.项目背景一、随着公司的快速发展,企业人员和经营规模不断壮大。为了提高工程管理效率、减轻劳动强度、提高信息处理速度和准确性,公司对内部工程管理的提升提出了更高的要求。二、企业通过

基于Matlab实现自动泊车(垂直泊车)

自动泊车是一项非常有趣和实用的技术,它可以让车辆在没有人为干预的情况下自动停放在合适的位置上。在这篇文章中,我们将介绍如何使用Matlab实现自动泊车。首先,我们需要了解自动泊车的基本原理。自动泊车系统通常包括车辆、传感器和控制算法。传感器可以用来检测周围的环境,例如通过摄像头、超声波传感器或激光雷达来检测车辆周围的障

数据治理在数字化转型中的重要性

在当今数字化时代,企业的成功与否往往取决于它们对数据的处理和管理能力。数据治理作为数字化转型的关键组成部分,对于帮助企业有效管理和利用数据,实现业务增长和创新至关重要。本文将探讨为什么数字化转型必须进行数据治理,并介绍数据治理的几个关键优势。随着技术的进步和数字化转型的发展,大量的数据被不断产生和积累。这些数据代表了企

WPF中DataGrid控件绑定数据源

步骤创建数据源:首先,我们需要创建一个数据源,可以是一个集合(如List、ObservableCollection等),也可以是一个DataTable对象。数据源中的每个元素代表一行数据。设置DataGrid的ItemsSource属性:在XAML中,我们可以通过设置DataGrid的ItemsSource属性来将数据

视频汇聚/视频云存储/视频监控管理平台EasyCVR分发rtsp流起播慢优化步骤详解

安防视频监控/视频集中存储/云存储/磁盘阵列EasyCVR平台可拓展性强、视频能力灵活、部署轻快,可支持的主流标准协议有国标GB28181、RTSP/Onvif、RTMP等,以及支持厂家私有协议与SDK接入,包括海康Ehome、海大宇等设备的SDK等。平台既具备传统安防视频监控的能力,也具备接入AI智能分析的能力,可拓

​LeetCode解法汇总2490. 回环句

目录链接:力扣编程题-解法汇总_分享+记录-CSDN博客GitHub同步刷题项目:https://github.com/September26/java-algorithms原题链接:力扣描述:句子是由单个空格分隔的一组单词,且不含前导或尾随空格。例如,"HelloWorld"、"HELLO"、"helloworldh

Docker从认识到实践再到底层原理(五)|Docker镜像

前言那么这里博主先安利一些干货满满的专栏了!首先是博主的高质量博客的汇总,这个专栏里面的博客,都是博主最最用心写的一部分,干货满满,希望对大家有帮助。高质量博客汇总然后就是博主最近最花时间的一个专栏《Docker从认识到实践再到底层原理》希望大家多多关注!Docker从认识到实践再到底层原理第五章-镜像Docker镜像

飞行动力学 - 基础点摘要整理

飞行动力学-基础点摘要整理随着飞行动力学视频完整看了一遍,大体对飞行动力学有了基本的了解。从其根本原理和概念来看,并不是非常复杂,将经典力学用于飞机,进行了各种飞行场景的解析。当然,一遍也只能知道一个大概,不过对于从来没有接触过飞行动力学的我来说,是一个全新的角度对于经典力学的应用。顺便也对于之前整理的一些摘要或者说课

热文推荐