如何解决求职面试算法?
更新:可以请原谅我对n的最后评论。 “代词”米的答案?
请注意:,我之前曾问过这个问题,但这完全是一团糟,所以我以原始格式写了更多细节。
问题:
我正在管理n位参与者(从1到N的每个索引)之间的投票系统,在这里我要支持以下功能:
- Init(N)-初始化数据结构。 -O(1)
- 投票(j,i)-将j投票给i的人(恰好1)添加到结果表中-不允许某人对自己投票。 -O(1)
- 投票人数(i)-返回投票给i的人数。 -O(1)
- 来源(j)-返回人物j给予他人的票数。 -O(1)
- 最喜欢的(k)-根据获得的票数打印排名靠前的参与者(降序排列)。 -O(k)
- Avoided()-打印所有未投票的参与者。 -O(r),其中r是打印的参与者的数量
在此问题中,空间复杂度应为 O(N)。
仅允许使用数组和(双重)链接列表。
我做了什么?
我只需声明一个大小为N的数组,每个单元格都包含值,就可以轻松地解决1-4。 got
和sent
。当i
对j
进行投票时,我将j
的价值增加了,并将i
的价值增加了一个。
我仍然不知道如何以所需的复杂度求解5和6。
注意:我在寻找算法/想法而不是实际代码。
解决方法
请注意,对于每个操作,被投票的候选人的得分都会增加一个。
这开启了一种新策略-与其将候选人映射到其分数,不将其映射到具有该分数的候选人列表。
这可以很简单地实现为候选列表列表(在模板中如语法:list<list<Candidate>>
)。
此外,保留一个将每个候选编号映射到实际Candidate
元素的指针的数组。
初始值为similar way you initialize an array in O(1)的所有候选者的隐式设置为0的候选者列表。
- 投票时:
- 您可以从参考文献中找到候选人:O(1)
- 您将其从当前列表中删除,并将其添加到下一个列表:O(1)
- 要在
Avoided()
中支持O(r)
:如果“ 0”列表中的元素数少于一半,请将其更改为常规列表。 - 如果表示分数的上一个元素现在没有候选者,请将其删除,然后将先前的分数直接链接到下一个(例如,如果没有分数为3的候选者,请连接
2<->4
),这可以确保{{1 }}的空间,因为没有太多的空列表节点。
- 通过从头到尾迭代得分列表(在输出
O(n)
个候选者之后停止),现在O(k)
中获得topK很容易并完成 - 如果避免了一半以上的候选者,则避免为
k
,否则,由于插入中的优化(3),O(n) = O(r)
得以避免。
这里是实现避免()的另一种方法。将两个数字与每个被投票的人相关联,即开始投票和结束投票。最初,所有元素都设置为None
(可以使用O(1)数组初始化技巧来完成)。
人m
初次投票时,更新startOfRun
和endOfRun
数组:
if startOfRun[m-1] != None and startOfRun[m+1] == None
endOfRun[startOfRun[m-1]] = m
else if startOfRun[m-1] == None and startOfRun[m+1] != None
startOfRun[endOfRun[m+1]]
else if startOfRun[m-1] != None and startOfRun[m+1] != None
endOfRun[startOfRun[m-1]] = endOfRun[m+1]
startOfRun[endOfRun[m+1]] = startOfRun[m-1]
else
startOfRun[m] = m
endOfRun[m] = m
(为简洁起见,省略了边缘条件)。
现在,您有许多被投票支持的人,您可以轻松地从开始到结束进行投票。运行中的数字都是错误的,但是我们不在乎它们。有O(r)次跑步,因此您可以跳过O(r)中所有被投票支持的人。
这是实现Favored()的另一种方法。有两个数组,(1)按分数排序的扩展人员数组,以及(2)从分数到第一个数组中最后一个具有不小于该分数的人的索引的映射(如果没有这样的人,则{ {1}})。最初,第一个数组为空,第二个数组包含None
。示例:
None
首次对某人进行投票后,会将其添加到得分为1的数组末尾,并更新(array 1)
(index) 1 2 3 4 5 6 7 8 9
person 3 6 5 1 4 2 8 9 7
score 7 7 7 5 5 3 2 2 2
(array 2)
score 1 2 3 4 5 6 7 8 9
index in 1st 9 9 6 5 5 3 3 - -
。一旦该人再次被投票,它就会与数组中具有相同分数的第一个人交换,分数会增加,第二个数组会被更新(我们只需要更新一个元素,即对应于新元素的元素即可)得分)。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。