【LeetCode】398. 随机数索引

170 阅读2分钟

image.png

一起养成写作习惯!这是我参与「掘金日新计划 · 4 月更文挑战」的第27天,点击查看活动详情

测试岗位也越来卷了,除了基本的功能测试外,还要有编程基础、脚本经验才脱颖而出。

怎么才能提高我们的编程能力呢,刷LeetCode是最佳的途径之一,话不多数,刷题走起~

一、题目描述:

  • 题目内容

    image.png

  • 题目示例

    image.png

  • 题目解析

    • 实现 Solution 类,传入 nums 列表
    • pick 函数实现随机索引函数
    • nums 列表长度在2^31 - 1
    • 最多调用 pick 函数 10^4 次

二、思路分析:

今天我们拿到本题,是一道关于面向对象类编程。要求实现一个类,在nums列表中随机返回指定的target值索引。

  • 如果 nums 列表中,无法找到 target 值,则返回null
  • 如果 nums 列表中,存在 target 值,则随机返回索引坐标
  • 每个索引返回的概率都相同

读完题意后,要在 nums 列表中返回指定 target 值随机索引,最简单的思路就是使用 哈希表

  • 方法一:哈希表迭代

    • 定义一个字典变量numsdict,存储nums列表中元素作为key值,元素所在位置索引存储在value中
    • 字典 value 类型以列表形式展示
    • Solution 类初始化时,则使用for循环遍历nums元素,将所有的元素存储在numsdict中
    • Solution 对象调用pick()方法时,调用random随机函数在numsdict[target]值中取出任意一个值

    根据以上思路,我们使用Python可以很容易实现,代码如下:

    class Solution(object):
    
        def __init__(self, nums):
            """
            :type nums: List[int]
            """
            self.nums = nums
            self.numsdict = {}
    
            for i in range(len(self.nums)):
    
                if self.nums[i] in self.numsdict:
    
                    self.numsdict[nums[i]].append(i)          
                else:
    
                    self.numsdict[nums[i]] = [i]
    
        def pick(self, target):
            """
            :type target: int
            :rtype: int
            """
            return random.choice(self.numsdict[target])
    

针对随机抽样的问题,有一个便捷的算法:储水池抽样

  • 什么是储水池抽样?

    • 储水池:顾名思义就是将符合的样本放在水池中
    • 抽样:在指定水池中抽取样本。样本抽出的概率是一样的
  • 方法二:储水池抽样

    • 只需要在pick函数中实现随机索引算法
    • 遍历nums列表,当nums[i]与target值相等时,随机选择区间 [1,tmp) 取任意数
    • 在区间中取出的数等于1时,则ans赋值为索引i
    class Solution(object):
        def __init__(self, nums):
            """
            :type nums: List[int]
            """
            self.nums = nums
        def pick(self, target):
            """
            :type target: int
            :rtype: int
            """
            tmp , ans= 1,0
            for i in range(len(self.nums)):
    
                if self.nums[i] == target:
    
                    if randint(1,tmp) == 1:                    
                        ans = i
                    tmp = tmp + 1
    
            return ans
    
    

三、总结:

本题考察的是随机抽样算法,储水池抽样算法,AC记录如下:

image.png

时间复杂度O(1),pick 为 O(n),其中 n 是 nums 的长度

空间复杂度O(1),只需要常数的空间保存若干变量

以上是本期内容,欢迎大佬们点赞评论,下期见~~