📜  门| GATE CS 2021 |套装2 |第61章(1)

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

门 | GATE CS 2021 |套装2 |第61章

本文是关于 Gate 程序员考试 2021 年套装2中第61章的介绍。

题目简介

题目编号:CS 2021 套装2 Q61

考试名称:GATE CS

题目类型:编程

考试时间:3小时

分值:100分

题目描述

本题要求编写一个程序,该程序接受两个整数 n 和 k,然后在范围 [1, n] 中找到所有的 i,使得 i 的二进制表示中恰好有 k 个 1。

你的程序需要实现函数 find_numbers_with_k_bits_set(n: int, k: int) -> List[int],其中:

  • n:一个整数,表示找寻范围的上界
  • k:一个整数,表示要找到 i 的二进制表示中恰好有 k 个 1

函数的返回值为一个整数列表,其中包括所有的 i。

输入

输入由两个整数 n 和 k 以空格分隔的形式给出。

输出

输出是一个逗号分隔的整数列表,列表中包括所有恰好有 k 个 1 的 i。

样例
输入样例 1
20 3
输出样例 1
3,5,6,9,10,12
输入样例 2
30 2
输出样例 2
1,2,4,8,16
解题思路

本题可以使用暴力法来解决,对于范围内的每个整数,我们可以遍历它的二进制表示,统计其中 1 的数量,如果与 k 相等,则将其加入结果列表中。

对于 n 的范围而言,二进制表示中最多可包含 log(n) 个 1,因此最坏情况下时间复杂度为 O(n*log(n))。

实际上可以优化到 O(n),实现方式是利用二进制转换的技巧:如果 i 表示为二进制,那么将 i 小于等于 n 的所有数都右移,直到它们的二进制表示中都没有超过 i 的二进制表示中 1 的个数。这样,寻找具有 k 个 1 的 i 就可以通过遍历 i 和右移的代价来完成。

代码实现
from typing import List

def find_numbers_with_k_bits_set(n: int, k: int) -> List[int]:
    res = []
    for i in range(1, n+1):
        count = 0
        for c in bin(i):
            if c == '1':
                count += 1
        if count == k:
            res.append(i)
    return res