游戏中的随机抽样算法

相关题目:
382. 链表随机节点
384. 打乱数组
398. 随机数索引

文章详解:
游戏中的随机抽样算法

python 复制代码
class ListNode:
    def __init__(self, val=0, next=None):
        self.val = val
        self.next = next
        
class RandListNode:
    """
    382. 链表随机节点
    https://leetcode.cn/problems/linked-list-random-node/
    """
    def __init__(self, head: ListNode):
        self.head = head
        self.r = random.Random()

    def getRandom(self) -> int:
        i, res = 0, 0
        p = self.head
        # while 循环遍历链表
        while p:
            i += 1
            # 生成一个 [0, i) 之间的整数
            # 这个整数等于 0 的概率就是 1/i
            if 0 == self.r.randint(0, i-1):
                res = p.val
            p = p.next
        return res


class ShuffleArray:
    """
    384. 打乱数组
    https://leetcode.cn/problems/shuffle-an-array/
    """
    def __init__(self, nums: List[int]):
        self.nums = nums

    def reset(self) -> List[int]:
        return self.nums

    def shuffle(self) -> List[int]:
        copy = self.nums.copy()
        n = len(self.nums)
        for i in range(n):
            # 生成一个 [i, n-1] 区间内的随机数
            r = i + random.randint(0, n-i-1)
            # 交换 nums[i] 和 nums[r]
            copy[i], copy[r] = copy[r], copy[i]
        return copy


class RandomIndex:
    """
    398. 随机数索引
    https://leetcode.cn/problems/random-pick-index/description/
    """
    def __init__(self, nums: List[int]):
        self.nums = nums
        # self.rand = random.Random()

    def pick(self, target: int) -> int:
        count, res = 0, -1
        for i in range(len(self.nums)):
            if self.nums[i] != target:
                continue
            count += 1
            if random.randint(1, count) == 1:
                res = i
        return res

from collections import defaultdict
from random import choice
class RandomIndex2:
    """
    398. 随机数索引
    """
    def __init__(self, nums: List[int]):
        self.pos = defaultdict(list)
        for i, num in enumerate(nums):
            self.pos[num].append(i)

    def pick(self, target: int) -> int:
        return choice(self.pos[target])
相关推荐
小小小小王王王7 分钟前
求猪肉价格最大值
数据结构·c++·算法
岁忧31 分钟前
(LeetCode 面试经典 150 题 ) 58. 最后一个单词的长度 (字符串)
java·c++·算法·leetcode·面试·go
BIYing_Aurora38 分钟前
【IPMV】图像处理与机器视觉:Lec13 Robust Estimation with RANSAC
图像处理·人工智能·算法·计算机视觉
martian6652 小时前
支持向量机(SVM)深度解析:从数学根基到工程实践
算法·机器学习·支持向量机
孟大本事要学习2 小时前
算法19天|回溯算法:理论基础、组合、组合总和Ⅲ、电话号码的字母组合
算法
??tobenewyorker3 小时前
力扣打卡第二十一天 中后遍历+中前遍历 构造二叉树
数据结构·c++·算法·leetcode
让我们一起加油好吗3 小时前
【基础算法】贪心 (二) :推公式
数据结构·数学·算法·贪心算法·洛谷
贾全3 小时前
第十章:HIL-SERL 真实机器人训练实战
人工智能·深度学习·算法·机器学习·机器人
GIS小天4 小时前
AI+预测3D新模型百十个定位预测+胆码预测+去和尾2025年7月4日第128弹
人工智能·算法·机器学习·彩票
满分观察网友z4 小时前
开发者的“右”眼:一个树问题如何拯救我的UI设计(199. 二叉树的右视图)
算法