当前位置: 首页 > news >正文

DeepSeek LeetCode 3821. 二进制中恰好K个1的第N小整数 Python3实现

看到你给出的函数签名 def nthSmallest(self, n: int, k: int) -> int,这是 LeetCode 3821 的标准接口。我来提供完整的、可直接提交的解法:

解法一:组合计数法(推荐)

```python
class Solution:
def nthSmallest(self, n: int, k: int) -> int:
"""
返回二进制表示中恰好有 k 个 1 的第 n 小的正整数
"""
# 计算组合数 C(a, b)
def comb(a: int, b: int) -> int:
if b < 0 or b > a:
return 0
if b > a - b:
b = a - b
res = 1
for i in range(1, b + 1):
res = res * (a - b + i) // i
return res

# 第 1 步:确定答案的二进制长度
length = k # 最短长度就是 k(全为1)
while True:
# 长度为 length 时,首位必须是1,从剩余 length-1 位中选 k-1 个位置放1
cnt = comb(length - 1, k - 1)
if n > cnt:
n -= cnt
length += 1
else:
break

# 第 2 步:在长度为 length 的数中找第 n 个
ans = 1 << (length - 1) # 最高位固定为1
remaining_ones = k - 1 # 还需要放的1的个数
pos = length - 2 # 从次高位开始(索引从0开始)

while remaining_ones > 0 and pos >= 0:
# 如果当前位置放0,后面 pos 个位置能组成的方案数
cnt = comb(pos, remaining_ones)

if n > cnt:
# 跳过所有当前位置为0的情况,当前位置放1
n -= cnt
ans |= (1 << pos)
remaining_ones -= 1

pos -= 1

return ans
```

解法二:位运算生成法

```python
class Solution:
def nthSmallest(self, n: int, k: int) -> int:
"""
使用位运算生成恰好 k 个 1 的二进制数
"""
# 最小的数:最低的 k 位为 1
num = (1 << k) - 1

# 生成第 n 个数(从第1个开始)
for _ in range(n - 1):
# 找到最右边的非拖尾 1(即最右边的 "01" 模式)
# 例如:011100 -> 100011
smallest = num & -num # 最低位的1
ripple = num + smallest # 将连续的1进位
ones = ((num ^ ripple) >> 2) // smallest # 计算需要补的1的个数
num = ripple | ones

return num
```

解法三:递归法(更直观)

```python
class Solution:
def nthSmallest(self, n: int, k: int) -> int:
"""
递归构造:固定首位,递归处理剩余位
"""
def comb(a: int, b: int) -> int:
if b < 0 or b > a:
return 0
if b > a - b:
b = a - b
res = 1
for i in range(1, b + 1):
res = res * (a - b + i) // i
return res

def build(length: int, k: int, n: int) -> int:
"""在长度为 length 的数中找第 n 个(首位已经固定为1)"""
if length == k: # 所有位都是1
return (1 << length) - 1
if k == 0: # 没有1了
return 0

# 次高位放0,后面 length-1 位中选 k 个
cnt_with_zero = comb(length - 1, k)

if n <= cnt_with_zero:
# 第 n 个在次高位为0的分支中
return build(length - 1, k, n)
else:
# 第 n 个在次高位为1的分支中
return (1 << (length - 1)) + build(length - 1, k - 1, n - cnt_with_zero)

# 确定长度
length = k
while True:
cnt = comb(length - 1, k - 1)
if n > cnt:
n -= cnt
length += 1
else:
break

return build(length, k, n)
```

测试验证

```python
if __name__ == "__main__":
sol = Solution()

# 测试用例
test_cases = [
(1, 2), # 3 (11)
(2, 2), # 5 (101)
(3, 2), # 6 (110)
(4, 2), # 9 (1001)
(5, 2), # 10 (1010)
(1, 1), # 1 (1)
(2, 1), # 2 (10)
(3, 1), # 4 (100)
(1, 3), # 7 (111)
(2, 3), # 11 (1011)
]

for n, k in test_cases:
result = sol.nthSmallest(n, k)
print(f"n={n}, k={k} -> {result} (binary: {bin(result)})")
```

复杂度分析

· 时间复杂度:O(L),其中 L 是答案的二进制长度,对于 32 位整数最多 32 步
· 空间复杂度:O(1)

解法一最优,因为它直接通过组合数学定位,不需要迭代 n 次。当 n 很大时(如 10^9),解法二会超时,而解法一依然高效。

http://www.cnnetsun.cn/news/3867713.html

相关文章:

  • QKeyMapper:Windows平台终极跨设备按键映射解决方案
  • 西班牙智慧灌溉阀控器物联网卡:本土网络低功耗适配
  • Unity动态天气系统UniStorm:从体积云渲染到游戏玩法集成
  • Unity启动画面全解析:从内置配置到自定义加载场景的实战优化
  • 数据库期末急救指南:核心概念、SQL实战与高频考点解析
  • 集团网站群建设:打破信息孤岛,打造数字化协同新生态的实战思考
  • UE4抛射物运动方案:ProjectileMovement与物理模拟的冲突与融合
  • 微信网页版免安装完整指南:5分钟解锁公司电脑限制的终极方案
  • 基于PaddleOCR与大模型的文档智能解析:从视觉感知到认知理解
  • 3分钟掌握ECharts动态液位图表:让你的数据可视化生动起来![特殊字符]
  • 股票短期交易策略:超跌反弹与趋势惯性的实战解析
  • MIPI DSI协议解析与实战:从信号完整性到Linux驱动调试
  • Open-Meteo:重新定义企业级气象数据服务的开源架构
  • 中小企业网站建设需要些什么:从0到1的避坑指南与实战解析
  • 基于主从博弈的多主体综合能源系统优化调度
  • WarcraftHelper魔兽争霸3终极优化方案:5大核心功能解决现代系统兼容性问题
  • 亮点企业分析——智推时代GenOptima
  • Infoseek舆情监测系统:配置部署与智能分析实战
  • 美工产出种草图速度慢,易元 AI 商拍能否批量制图
  • 抖音批量下载工具完全指南:3步实现无水印视频自动化收集
  • o2o网站建设方案怎么落地?老鸟教你从0到1搭建高转化线下线上互联平台
  • KepWare工业通讯协议转换与OPC配置实战指南
  • 2026年抖音运营公司选型指南:从流量迷思到长效增长的务实路径
  • MQTT在污水处理物联网中的应用:从协议分析到EMQX部署
  • 香港服务器凭什么火?免备案+低延迟的技术真相
  • 揭秘姜堰网站建设背后的真相:如何为本地企业打造真正高转化率的数字名片?
  • 破解AI绘画插件管理难题:ComfyUI-Manager如何重构工作流生态
  • Spring全家桶全彩笔记(终极版):Java初学者快速上手必备!
  • UART串口通信:从异步通信原理到嵌入式开发实战
  • 3分钟搞定多平台直播:OBS多路推流插件终极指南