掌握位运算,刷题打卡不求人:线性时间解决「整数二进制中 1 的个数」
2023-12-11 23:50:25
位运算:算法优化的利器
计算机科学中的位运算是一种强大的工具,它可以在二进制层面上操作位和数字。它在解决编程问题,尤其是算法优化方面发挥着至关重要的作用。对于初学者来说,掌握位运算可以显著提高刷题打卡的效率。
本文将带领你深入探索位运算在解决一道经典算法问题中的应用——「整数二进制中 1 的个数」。我们将从最基础的概念讲起,逐步拆解算法,最终实现用线性时间 O(n) 一趟扫描的优雅解法。
位运算基础
在开始之前,让我们先回顾一下位运算的基础知识。
- 二进制数: 计算机中使用的数字系统,由 0 和 1 两个数字组成。
- 位: 二进制数中的单个数字。
- 位运算: 在位级别上操作数字的运算,包括按位与 (&)、按位或 (|) 和按位异或 (^) 等。
「整数二进制中 1 的个数」问题
题目: 给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。
示例:
- 输入:num = 5
- 输出:[0,1,1,2,1,2]
- 0 的二进制表示为 0,没有 1。
- 1 的二进制表示为 1,有 1 个 1。
- 2 的二进制表示为 10,有 1 个 1。
- 3 的二进制表示为 11,有 2 个 1。
- 4 的二进制表示为 100,有 1 个 1。
- 5 的二进制表示为 101,有 2 个 1。
线性时间 O(n) 解法
我们首先考虑一个朴素的解法,即遍历每个数字,逐个检查其二进制位。时间复杂度为 O(n*sizeof(integer)),其中 sizeof(integer) 是整数在计算机中所占的位数。
为了优化算法,我们需要一个更巧妙的方法。我们可以利用这样一个事实:任何数字 i 的二进制表示中 1 的个数等于其后继数字 i+1 二进制表示中 1 的个数,加上 i 的二进制表示中最低位是否是 1。
例如,1 的二进制表示为 1,而 2 的二进制表示为 10。可以看到,1 的二进制表示中最低位是 1,而 2 的二进制表示中最低位是 0。因此,1 的二进制表示中 1 的个数为 1,而 2 的二进制表示中 1 的个数为 1 加上最低位的 0,即 1。
基于这个原理,我们可以从 num = 0 开始,逐个计算每个数字 i 二进制表示中 1 的个数。如果 i 的最低位是 1,则其二进制表示中 1 的个数为其后继数字二进制表示中 1 的个数加 1;否则,其二进制表示中 1 的个数与其后继数字相同。
def countBits(num):
dp = [0] * (num + 1)
for i in range(1, num + 1):
dp[i] = dp[i >> 1] + (i & 1)
return dp
在这个算法中,我们使用了一个动态规划的思想。dp[i]
表示数字 i 的二进制表示中 1 的个数,i >> 1
表示将 i 右移一位,相当于除以 2,而 i & 1
表示 i 的最低位,如果最低位是 1,则其值为 1。
时间复杂度为 O(n),因为我们只需要遍历每个数字一次。空间复杂度为 O(n),因为我们需要存储每个数字的二进制表示中 1 的个数。
总结
通过本文的讲解,你应该已经掌握了如何使用位运算解决「整数二进制中 1 的个数」算法问题。这种巧妙的方法不仅可以提高刷题打卡的效率,还可以让你在算法竞赛中脱颖而出。
在学习位运算时,重要的是要循序渐进,从基础概念到实际应用。通过不断的练习和探索,你一定能够熟练掌握这项强大的工具。
常见问题解答
- 什么是位运算?
答:位运算是在位级别上操作数字的运算,包括按位与、按位或和按位异或。 - 位运算在算法优化中有哪些应用?
答:位运算可以用于解决各种算法问题,例如整数二进制中 1 的个数、二进制加法和乘法。 - 如何用位运算解决整数二进制中 1 的个数问题?
答:我们可以使用动态规划的方法,利用这样一个事实:任何数字 i 的二进制表示中 1 的个数等于其后继数字 i+1 二进制表示中 1 的个数,加上 i 的二进制表示中最低位是否是 1。 - 线性时间 O(n) 解法的原理是什么?
答:该算法通过逐个计算每个数字 i 的二进制表示中 1 的个数来工作。如果 i 的最低位是 1,则其二进制表示中 1 的个数为其后继数字二进制表示中 1 的个数加 1;否则,其二进制表示中 1 的个数与其后继数字相同。 - 位运算对提高刷题效率有哪些好处?
答:位运算可以帮助你解决算法问题,提高刷题打卡的效率,并让你在算法竞赛中脱颖而出。