338、比特位计数

  1. 338、比特位计数
    1. 示例 1:
    2. 示例 2:
    3. 进阶:
  • 题解
    1. 1、比较每一个二进制位
    2. 2、动态规划+最高有效位
    3. 3、动态规划+最低有效位
    4. 4、动态规划+最后设置位
  • 338、比特位计数

    给定一个非负整数 num。对于 0 ≤ i ≤ num 范围中的每个数字 i ,计算其二进制数中的 1 的数目并将它们作为数组返回。

    示例 1:

    输入: 2
    输出: [0,1,1]
    

    示例 2:

    输入: 5
    输出: [0,1,1,2,1,2]
    

    进阶:

    • 给出时间复杂度为O(n*sizeof(integer))的解答非常容易。但你可以在线性时间O(n)内用一趟扫描做到吗?
    • 要求算法的空间复杂度为O(n)。
    • 你能进一步完善解法吗?要求在C++或任何其他语言中不使用任何内置函数(如 C++ 中的 __builtin_popcount)来执行此操作。

    题解

    1、比较每一个二进制位

    • Pop count
    • 代码
    // java
    class Solution {
        public int[] countBits(int num) {
            int[] res = new int[num+1];
            res[0] = 0;
            for (int i = 1;i <= num;i++) {
                res[i] = getNumberOf1(i);
            }
            return res;
        }
        
        private int getNumberOf1(int i) {
            int ans = 0;
            int mask = 1;
            while(mask <= i) {
                if ((i&mask) == mask) {
                    ans++;
                }
                mask <<= 1; 
            }
            return ans;
            // Pop count
            // int count;
            // for (count = 0; x != 0; ++count)
            //   x &= x - 1; //zeroing out the least significant nonzero bit
            // return count;
    
            // 作者:LeetCode
            // 链接:https://leetcode-cn.com/problems/counting-bits/solution/bi-te-wei-ji-shu-by-leetcode/
            // 来源:力扣(LeetCode)
            // 著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
        }
    }
    

    2、动态规划+最高有效位

    • 两个数字二进制表示,相差的最高位(2^m),利用之
    • Pop acount P(x) :
      • $P(x + b) = P(x) + 1, b = 2^m > x$
    • 代码
    // Java
    class Solution { 
        public int[] countBits(int num) {
            // 返回的结果
            int[] ans = new int[num + 1];
            // 辅助变量
            int i = 0, b = 1;
            // 遍历每一位
            while (b <= num){
                // 处理0~num里面的每一个数字
                // i < b 是进位终止,有2 4 8 16 。。。
                // i+b <= num 是结束终止
                while(i < b && i + b <= num) {
                    // ans[i]都是已经计算过的解
                    ans[i + b] = ans[i] + 1;
                    ++i;
                }
                i = 0;// 重置
                b <<= 1;// 左移一位
            }
            return ans;
        }
    }
    

    3、动态规划+最低有效位

    • 两个数字二进制表示,相差的最低位(x/2 + x%2),利用之
    • $P(x) = P(x >> 2) + (x % 2)$
    • 代码
    // Java
    class Solution { 
        public int[] countBits(int num) {
            // 返回的结果
            int[] ans = new int[num + 1];
            // 循环处理
            for (int i = 1;i <= num;i++) {
                // i>>1 ==> i/2  i & 1 ==> i%2
                ans[i] = ans[i>>1] + i&1;
            }
            return ans;
        }
    }
    

    4、动态规划+最后设置位

    • 对于x, 其与x-1相差的1的个数用下面的公式:
      • $P(x) = P(x & (x - 1)) + 1$
    • 代码
    // Java
    class Solution { 
        public int[] countBits(int num) {
            // 返回的结果
            int[] ans = new int[num + 1];
            // 循环处理
            for (int i = 1;i <= num;i++) {
                ans[i] = ans[i & (i - 1)] + 1;
            }
            return ans;
        }
    }
    

    转载请注明来源,欢迎对文章中的引用来源进行考证,欢迎指出任何有错误或不够清晰的表达。可以在下面评论区评论,也可以邮件至 1056615746@qq.com

    💰

    Title:338、比特位计数

    Count:702

    Author:攀登

    Created At:2020-07-26, 00:19:44

    Updated At:2024-06-15, 15:52:32

    Url:http://jiafeimao-gjf.github.io/2020/07/26/338%E3%80%81%E6%AF%94%E7%89%B9%E4%BD%8D%E8%AE%A1%E6%95%B0/

    Copyright: 'Attribution-non-commercial-shared in the same way 4.0' Reprint please keep the original link and author.

    ×

    Help us with donation