📜  从N个自然数中分离出奇数和奇数后,计数第K个数字中的设置位(1)

📅  最后修改于: 2023-12-03 14:49:20.535000             🧑  作者: Mango

从N个自然数中分离出奇数和奇数后,计数第K个数字中的设置位

题目描述

给定正整数 $N$,从 $1$ 到 $N$ 中选择所有奇数,组成一个新的序列 $S$。现在让你从序列 $S$ 中计算出第 $K$ 个数字的二进制表示中的设置位数量。

例如:当 $N=10$, $K=3$ 时,$S$ 序列为 $[ 1, 3, 5, 7, 9 ]$,那么第 $3$ 个数字 $5$ 的二进制表示为 $101$ ,其中设置位数量为 $2$。

解题思路

首先,我们需要计算出 $1$ 到 $N$ 的奇数个数 $s$,然后将其转换为 $01$ 序列。例如,当 $N=10$ 时,奇数个数为 5,其对应的 $01$ 序列为 $[0, 1, 1, 0, 1]$。

接下来,我们考虑如何查询第 $K$ 个奇数的二进制表示中的设置位数量。首先将 $K$ 转换为二进制表示,假设其长度为 $len$。然后依次遍历二进制表示中的每一位,如果该位为 $1$,则说明该位代表的是一个设置位,那么该位所处的索引与 $01$ 序列中的值相对应,我们将该位置的 $1$ 累加到结果中即可。

代码实现
def count_set_bits(n: int, k: int) -> int:
    # 计算奇数个数并转换为 01 序列
    odd_count = (n + 1) // 2
    odd_sequence = [0] * odd_count
    for i in range(odd_count):
        odd_sequence[i] = (i * 2) + 1
    # 将 K 转换为二进制表示
    k_binary = bin(k)[2:]
    result = 0
    # 遍历二进制表示中的每一位,计算设置位数量
    for i in range(len(k_binary)):
        if k_binary[i] == '1':
            result += odd_sequence[len(k_binary) - i - 1]
    return result
测试样例
样例1
输入:
N = 10
K = 3
输出:
2
解释:
将奇数从 1 到 10 提取出来,得到序列 [1, 3, 5, 7, 9],其中第 3 个数字为 5,其二进制表示为 101,其中有 2 个设置位。
样例2
输入:
N = 12
K = 7
输出:
2
解释:
将奇数从 1 到 12 提取出来,得到序列 [1, 3, 5, 7, 9, 11],其中第 7 个数字为 11,其二进制表示为 1011,其中有 2 个设置位。
总结

本题解通过将奇数转换为 01 序列,再利用二进制的性质计算设置位数量,解决了从 $N$ 个自然数中分离出奇数和奇数后,计数第 $K$ 个数字中的设置位的问题。