398. 随机数索引
Posted 我要出家当道士
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了398. 随机数索引相关的知识,希望对你有一定的参考价值。
目录
1、Question
给定一个可能含有重复元素的整数数组,要求随机输出给定的数字的索引。 您可以假设给定的数字一定存在于数组中。
注意:
数组大小可能非常大。 使用太多额外空间的解决方案将不会通过测试。示例:
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);
2、Analysis
这题思路不难想,就是使用MAP进行存储,实现快速检索。C++、Java、GO类似的高级语言中都有现成的MAP类型可以使用,因为我使用的纯 C,所以需要自己实现一个MAP,稍微有点繁琐,但本来刷题就是为了提高自身能力,自己实现更能掌握细节。
我是使用线性数组 + 链表实现MAP,对于一个待存的数先对一个稍大的数进行取余操作求出其在线性数组中的位置,并存放在该位置的链表中。之所以使用链表,是为了解决hash冲突。
本题中还有两点需要注意:
1、存放负数。我是将负数转换为正数进行存放,但存在隐患,但在这题中没有暴露出来,可结合 注意点 2 进行思考。
2、重复的数的索引被找出来的概率相等。这个很简单,先找出来,再随机读取。
3、Code
typedef struct node
int num;
int index;
struct node *next;
Node;
typedef struct
Node *list;
int size;
Solution;
#define MAPSIZE 1000
#define NEWNODE (Node *)malloc(sizeof(Node))
Solution* solutionCreate(int *nums, int numSize)
Solution *obj = (Solution *)malloc(sizeof(Solution));
obj->list = (Node *)malloc(sizeof(Node) * MAPSIZE);
obj->size = numSize;
for (int i = 0; i < MAPSIZE; i++)
obj->list[i].next = NULL;
for(int i = 0; i < numSize; i++)
int num = nums[i] > 0? nums[i]: -nums[i];
int map_index = num % MAPSIZE;
Node *head = obj->list + map_index;
Node *node = NEWNODE;
node->num = num;
node->index = i;
node->next = NULL;
node->next = head -> next;
head->next = node;
return obj;
int solutionPick(Solution *obj, int target)
target = target > 0? target : -target;
int map_index = target % MAPSIZE;
Node *head = obj->list + map_index;
// 局限在 100,优化时可使用链表存储
int res[100], count = 0;
while(head->next != NULL)
head = head->next;
if (head->num == target)
res[count++] = head->index;
return res[rand()%count];
void solutionFree(Solution* obj)
for (int i = 0; i < MAPSIZE; i++)
Node *head = obj->list + i;
head = head->next;
while(head != NULL)
Node *node = head;
head = head->next;
free(node);
free(obj);
4、Execution
很久没刷题了,有点生疏了。
以上是关于398. 随机数索引的主要内容,如果未能解决你的问题,请参考以下文章