前言
好久没有抽时间刷题了,突然发现leetcode有个random标签,就好奇这下面是什么类型的题,结果没想到碰巧看到了这个在公司游戏化教学项目也有涉及的问题,遂顺手甩一篇题解。
在本文中,我会先给出该题的题解。之后,在后文的『扩展延伸』中给出该题缩小数据范围后的另一种更高效的解法,以及我在全日制游戏项目中遇到的与该问题相似的案例。
这题主要考点是二分查找,以及能否灵活的转化问题。此外,如果权值数组w
的长度范围没那么长,权值范围没那么大的话,考点就从二分查找变为哈希了。具体可以看我后文中的扩展延伸。
题解
解析
基本思想就是把各个位置的权值表现为在一个数值范围中占据的区间。具体过程为,构造一个总长度为权值列表w
中各值之和sumWeight
的列表weightRoute
。在随机选取位置时,rand一个数值weight
,此时,若存在下标index
,使 w e i g h t ∈ [ w e i g h t R o u t e [ i n d e x ] , w e i g h t R o u t e [ i n d e x + 1 ] ) weight \in [weightRoute[index], weightRoute[index+1] ) weight∈[weightRoute[index],weightRoute[index+1]),则下标index
即为我们要获取的坐标。后续搜索阶段的二分查找是基本操作了,思想也很简单,这里就不赘述了。
代码
构造阶段,时间复杂度为O(n),搜索阶段时间复杂度为O(logn)。
class Solution {
protected $sumWeight;
protected $length;
protected $weightRoute = [0];
function __construct(array $w) {
// sum total
$this->sumWeight