398. Random Pick Index
2016-09-11 12:13
323 查看
Given an array of integers with possible duplicates, randomly output the index of a given target number. You can assume that the given target number must exist in the array. Note: The array size can be very large. Solution that uses too much extra space will not pass the judge. Example: int[] nums = new int[] {1,2,3,3,3}; Solution solution = new Solution(nums); // pick(3) should return either index 2, 3, or 4 randomly. Each index should have equal probability of returning. solution.pick(3); // pick(1) should return 0. Since in the array only nums[0] is equal to 1. solution.pick(1);
这题其实不难,但有一个很有意思的点,我一开始想的是,数组本身是乱序的,我直接在坐标范围内产生一个随机数作为检索的开始,然后返回我遇到的第一个target值的坐标即可,听上去也没什么问题。可是在[1,2,3,3,3]这个例子就错了,测试用例拼命测试返回3的下标,看结果是不是在下标2,3,4之间均匀分布,结果我的代码就不可以,我看了看我的结果,2的比例明显多于3和4,我突然发现,如果数组不是随机排列,那么我的算法在这种重复数字扎堆出现的情况下就错了。拿这个例子来说,数组一共5个数,随机产生的检索起始数是A[0]到A[4]的概率是一样的,但这种情况下,起始是0,1,2的结果都是返回下标为2的那个3,所以这就是为什么我的返回结果里2的出现最多,理论上2的概率是另外俩单个概率的三倍了。
所以最后我还是直接检索了一遍原数组,然后将target的下标存起来,然后再存起来的下标里产生随机数选择一个返回。这样时间复杂度和空间复杂度都是O(n)。
class Solution { private: vector<int> num; public: Solution(vector<int> nums): num(nums) {} int pick(int target) { int len = num.size(); vector<int> ind; for (int i = 0; i < len; i++) { if (num[i] == target) ind.push_back(i); } int rd = rand() % ind.size(); return ind[rd]; } };
更好的解法后续再补充。
相关文章推荐
- Google Kubernetes设计文档之服务篇-转
- JZOJ4769. graph
- iOS中(相册)摄像头获取的图片上传至服务器被自动旋转了
- win10启动慢
- jQuery的扩展方法写法
- Cesium学习笔记(2)
- I2C接口与SPI和UART接口的区别
- 初识《大话设计模式》
- java多线程:synchronized
- 京东校招2017届应届生java研发岗,面试一,感想
- CCF 201509-3 我参考别人 100分
- Python 错误和异常小结
- mtk Android 常用编译命令
- Codeforces Problem 712C Memory and De-Evolution(贪心,逆推)
- HDU1548-A strange lift
- PHP入门教程之会话控制技巧(cookie与session)
- [置顶] HDU 4592 Boring Game(高斯消元好题)
- 为JavaScript内置对象扩展方法
- 9. 练习:将Eclipse plug-in转化成Eclipse 4 Application project
- 这个博主简易java部分写的不错,http://www.diguage.com/archives