力扣398.随机数索引

给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引。 您可以假设给定的数字一定存在于数组中
注意:
数组大小可能非常大。 使用太多额外空间的解决方案将不会通过测试。

示例:

int[] nums = new int[] {1,2,3,3,3};
Solution solution = new Solution(nums);

// pick(3) 应该返回索引 2,3 或者 4。每个索引的返回概率应该相等。
solution.pick(3);

// pick(1) 应该返回 0。因为只有nums[0]等于1。
solution.pick(1);

虽然题目注意上写着“数组大小可能非常大”,但是这是英文版给出的数据范围:

  • 1 <= nums.length <= 2 * 104
  • -231 <= nums[i] <= 231 - 1
  • target is an integer from nums.
  • At most 104 calls will be made to pick.

姑且理解为鼓励读者尽可能的优化空间复杂度。

思路:蓄水池采样法,可以在O(1)的空间复杂度下,对不定长数据流等概率抽取k个数据,本题中k=1。详见另一篇文章:https://www.cnblogs.com/Akisumu/articles/16189556.html

class Solution {
    vector<int>nums;
public:
    Solution(vector<int> &nums) : nums(nums) {}
    
    int pick(int target) {
        int ans;
        int cnt = 0;
        for(int i=0;i<nums.size();i++)
        {
            if(nums[i] == target)
            {
                cnt++;
                if(rand() % cnt <1)//小于抽取数据的数量,本题为1
                ans = i;
            }
        }
        return ans;
    }
};
posted @ 2022-04-25 16:02  Akisumu  阅读(31)  评论(0)    收藏  举报