跳到主要内容

398.随机数索引

链接:398.随机数索引
难度:Medium
标签:水塘抽样、哈希表、数学、随机化
简介:给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引。 您可以假设给定的数字一定存在于数组中。

题解 1 - cpp

  • 编辑时间:2022-04-25
  • 执行用时:92ms
  • 内存消耗:37.3MB
  • 编程语言:cpp
  • 解法介绍:排序后二分遍历。
class Solution {
public:
vector<int> idxs, nums;
int n;
Solution(vector<int> &nums) {
srand(time(0));
this->nums = nums;
n = nums.size();
for (int i = 0; i < n; i++) idxs.push_back(i);
sort(idxs.begin(), idxs.end(),
[&](int &i1, int &i2) -> bool { return nums[i1] < nums[i2]; });
}
int pick(int target) {
int start = find1(0, n, target);
int end = find2(start, n - 1, target);
return idxs[random(start, end)];
}
int find1(int l, int r, int target) {
int m;
while (l < r) {
m = (l + r) >> 1;
if (nums[idxs[m]] >= target)
r = m;
else
l = m + 1;
}
return l;
}
int find2(int l, int r, int target) {
int m;
while (l < r) {
m = (l + r + 1) >> 1;
if (nums[idxs[m]] <= target)
l = m;
else
r = m - 1;
}
return l;
}
int random(int a, int b) { return rand() % (b - a + 1) + a; }
};

题解 2 - cpp

  • 编辑时间:2022-04-25
  • 执行用时:44ms
  • 内存消耗:34.7MB
  • 编程语言:cpp
  • 解法介绍:水塘抽样。
class Solution {
public:
vector<int> nums;
int n;
Solution(vector<int>& nums) {
this->nums = nums;
n = nums.size();
srand(time(0));
}
int pick(int target) {
int cnt = 0, ans = 0;
for (int i = 0; i < n; i++) {
if (nums[i] != target) continue;
if (rand() % ++cnt == 0) {
ans = i;
}
}
return ans;
}
};