从N个数中等概率打印M个数

从N个数中等概率打印M个数

问题

【题目】
给定一个长度为N且没有重复元素的数组arr和一个整数n,实现函数等概率随机打印arr中的M个数。

【要求】

  1. 相同的数不要重复打印;
  2. 时间复杂度为 O ( M ) O(M) OM,额外空间复杂度为 O ( 1 ) O(1) O1
  3. 可以改变arr数组。

算法思路

不考虑额外空间复杂度为 O ( 1 ) O(1) O1的限制,创建一个状态数组或者哈希表记录已打印的数。
本题的小技巧是与最后一个位置的数值交换swap arr[cur], arr[n - 1 - i],很多有关等概率随机的题目沿用这个思路(e.g. 等概率随机快速获取key的结构


相应代码

def random_print_m_numbers(arr, m):
    if arr is None or m <= 0 or len(arr) < m:
        return
    n = len(arr)
    for i in range(m):
        cur = int(random.random() * (n - i))
        print(arr[cur], end=' ')
        # swap arr[cur], arr[n - 1 - i]
        temp = arr[cur]
        arr[cur] = arr[n - 1 - i]
        arr[n - 1 - i] = temp

# 简单测试
if __name__ == '__main__':
    arr = [1, 4, 9, 3, 8]
    random_print_m_numbers(arr, 2)

有任何疑问和建议,欢迎在评论区留言和指正!

感谢您所花费的时间与精力!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值