蓄水池演算法

2021-10-06 01:34:54 字數 2188 閱讀 9983

應用場景:用於解決海量不確定數量資料的隨機抽樣演算法

問題描述:給定乙個不固定長度的資料集合a,從a中等概率的選擇k個元素作為返回樣本

問題定義:

現在有一組數,不知道長度多少,請描述乙個演算法從這組數中隨機抽取k個數,使得每個數被取出來的概率相等。

思路:如果我們知道n的值,那麼問題就可以簡單的用乙個大隨機數rand()%n得到乙個確切的隨機位置,那麼該位置的物件就是所求的物件,選中的概率是1/n。

398. 隨機數索引

給定乙個可能含有重複元素的整數陣列,要求隨機輸出給定的數字的索引。 您可以假設給定的數字一定存在於陣列中。

注意:陣列大小可能非常大。 使用太多額外空間的解決方案將不會通過測試。

示例:int nums = new int ;

solution solution = new solution(nums);

// pick(3) 應該返回索引 2,3 或者 4。每個索引的返回概率應該相等。

solution.pick(3);

// pick(1) 應該返回 0。因為只有nums[0]等於1。

solution.pick(1);

1.直接改造蓄水池演算法

class solution:

def __init__(self, nums: list[int]):

self.data=nums

def pick(self, target: int) -> int:

tmp=[i for i in range(len(self.data)) if self.data[i]==target]

sample=[tmp[0]]

for i in range(1,len(tmp)):

j=random.randint(0,i)

if j>=1:continue

sample[j]=tmp[i]

return sample[0]

382. 鍊錶隨機節點

給定乙個單鏈表,隨機選擇鍊錶的乙個節點,並返回相應的節點值。保證每個節點被選的概率一樣。

高階:如果鍊錶十分大且長度未知,如何解決這個問題?你能否使用常數級空間複雜度實現?

示例:// 初始化乙個單鏈表 [1,2,3].

listnode head = new listnode(1);

head.next = new listnode(2);

head.next.next = new listnode(3);

solution solution = new solution(head);

// getrandom()方法應隨機返回1,2,3中的乙個,保證每個元素被返回的概率相等。

solution.getrandom();

1.模板題

class solution:

def __init__(self, head: listnode):

self.data=

while head:

head=head.next

def getrandom(self) -> int:

sample=[self.data[0]]

for i in range(1,len(self.data)):

j=random.randint(0,i)

if j>=1:continue

sample[j]=self.data[i]

return sample[0]

蓄水池演算法

參考文章 問題定義 給你乙個長度為n的鍊錶。n很大,但你不知道n有多大。你的任務是從這n個元素中隨機取出k個元素。你只能遍歷這個鍊錶一次。你的演算法必須保證取出的元素恰好有k個,且它們是完全隨機的 出現概率均等 求解蓄水池抽樣演算法 該演算法是針對從乙個序列中隨機抽取不重複的k個數,保證每個數被抽取...

蓄水池演算法

適用情況 從n個數中等概率隨機取出k個數,n很大,k也很大 n不固定增量型 內容 當i屬於1 k i入池 當i k i以概率k i決定是否進入池,1 k概率剔除池中乙個數 證明 1 當i 當k個數時,i留下概率 1 當k 1個數時,i被淘汰的概率 1 k k k 1 1 k 1 i留下概率 1 1 ...

蓄水池演算法

在乙個未知的池子裡選1個數字,讓他們被選擇概率一致。假設n的時候,前n個數字被選擇的概率都是1n 當為n 1時候,當前n 1這個數,我們選擇的概率是1n 1,其餘數字的概率是nn 1,那麼一共有n個數字的概率是1n 所以 n 1n 1 n 1 1n 1 具體演算法 使用的方式是i random.ra...