📜  资质 |门 CS 1998 |第 84 题(1)

📅  最后修改于: 2023-12-03 15:28:13.486000             🧑  作者: Mango

资质 | 门 CS 1998 | 第 84 题

这是一道来自“门 CS 1998”历年真题的编程题目,需要满足以下要求:

  • 语言不限,可使用任何编程语言完成;

  • 实现一个函数或方法,接受一个正整数 n 作为参数,返回一个长度为 n 的数组;

  • 数组中的第 i 个元素的值要等于 i 的二进制表示中 1 的个数,例如:

    • 当 n = 5 时,应该返回 [0, 1, 1, 2, 1],因为:

      • 0 的二进制表示是 0,其中的 1 的个数是 0;
      • 1 的二进制表示是 1,其中的 1 的个数是 1;
      • 2 的二进制表示是 10,其中的 1 的个数是 1;
      • 3 的二进制表示是 11,其中的 1 的个数是 2;
      • 4 的二进制表示是 100,其中的 1 的个数是 1。

此题考察二进制数的计算和位运算,可以通过递归、循环、查表等方法解决。具体实现方法可以参考以下思路:

  • 对于任意正整数 x,其二进制表示中 1 的个数等于 x 除以 2 取整后的整数的二进制表示中 1 的个数加上 x 除以 2 的余数,即:

    def count_bits(x: int) -> int:
        return count_bits(x // 2) + (x % 2) if x > 0 else 0
    
  • 在调用 count_bits 函数时,可以使用 memoization 技术缓存已经求解过的值,避免重复计算,提高程序性能,例如:

    def count_bits(n: int) -> List[int]:
        memo = [0] * (n + 1)
    
        def helper(x: int) -> int:
            if x == 0:
                return 0
            elif memo[x] > 0:
                return memo[x]
            else:
                memo[x] = helper(x // 2) + (x % 2)
                return memo[x]
    
        return [helper(i) for i in range(n + 1)]
    

最终的实现代码需要考虑输入的边界情况,例如当 n 小于等于 0 时应该返回空数组等。