游戏中的随机抽样算法

相关题目:
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])
相关推荐
橙几19 分钟前
击败了90%的解法?Two Sum 从 O(n²) 到 O(n) 的优化之路
算法
叶子爱分享33 分钟前
经典排序算法之归并排序(Merge Sort)
算法·排序算法
珹洺39 分钟前
C++算法竞赛篇:DevC++ 如何进行debug调试
java·c++·算法
呆呆的小鳄鱼1 小时前
leetcode:冗余连接 II[并查集检查环][节点入度]
算法·leetcode·职场和发展
墨染点香1 小时前
LeetCode Hot100【6. Z 字形变换】
java·算法·leetcode
沧澜sincerely1 小时前
排序【各种题型+对应LeetCode习题练习】
算法·leetcode·排序算法
CQ_07121 小时前
自学力扣:最长连续序列
数据结构·算法·leetcode
弥彦_2 小时前
cf1925B&C
数据结构·算法
YuTaoShao2 小时前
【LeetCode 热题 100】994. 腐烂的橘子——BFS
java·linux·算法·leetcode·宽度优先
向宇it2 小时前
【unity组件介绍】URP Decal Projector贴花投影器,将特定材质(贴花)投影到场景中的其他对象上。
游戏·3d·unity·c#·游戏引擎·材质