Leetcode之随机数索引

题目:

给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引。 您可以假设给定的数字一定存在于数组中。

注意:
数组大小可能非常大。 使用太多额外空间的解决方案将不会通过测试。

示例:

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

代码:

方法一——暴力使用哈希表存储每个值到其所有索引的映射。用rand函数随机选择一个索引返回即可。需要很多额外空间:

class Solution {
public:
    Solution(vector& nums) {
        for (int i = 0; i < nums.size(); i++) {
            mp[nums[i]].push_back(i);
        }
    }
    
    int pick(int target) {
        auto indices = mp[target];
        int r = rand() % indices.size();
        return indices[r];
    }

private:
    unordered_map> mp;
};


方法二——蓄水池抽样保存整个Nums数组的方法:

class Solution {
public:
    Solution(vector& nums) {
        this->nums = nums;
    }
    
    int pick(int target) {
        int cnt = 0;
        int index = -1;
        for (int i = 0; i < nums.size(); i++) {
            if (nums[i] == target) {
                cnt++;
                if (rand() % cnt == 0) {
                    index = i; // 1/i prob
                }
            }
        }

        return index;
    }

private:
    vector nums;
};


方法三——:

class Solution3 {
public:
    Solution3(vector& nums) {
        begin = nums.begin();
        end = nums.end();
    }
    
    int pick(int target) {
        int index = -1;
        int cnt = 0;
        int i = 0;
        for (auto iter = begin; iter != end; iter++) {
            if (*iter == target) {
                cnt++;
                if (rand() % cnt == 0) {
                    index = i; // 1/i prob choose current index
                }
            }
            i++;
        }

        return index;
    }

private:
    vector::iterator begin;
    vector::iterator end;
};

想法:思路和第二种相同,只不过是没有用整个vector空间;

你可能感兴趣的:(leetcode和机试题,leetcode)