398. 随机数索引

Posted 我要出家当道士

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了398. 随机数索引相关的知识,希望对你有一定的参考价值。

目录

1、Question

2、Analysis

3、Code

4、Execution 


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. 随机数索引的主要内容,如果未能解决你的问题,请参考以下文章

398. 随机数索引

398 Random Pick Index 随机数索引

398. 随机数索引Normal水塘抽样算法

「 每日一练,快乐水题 」398. 随机数索引

「 每日一练,快乐水题 」398. 随机数索引

LeetCode 398 随机数索引[水塘抽样] HERODING的LeetCode之路