【问题标题】:Function for getting the winner at a given instant of time在给定时刻获得获胜者的功能
【发布时间】:2017-08-20 17:59:52
【问题描述】:

我想与聪明的程序员讨论这个问题,这个问题在最近的一次采访中被问到,引导你了解我的方法,并询问你将如何有效地解决这个问题。非常感谢您的见解:)

假设给你一个数组:

 arr = [[sam,123],[ram,124],[kris,125],[hen,127],[kris,135], [sam,140],...] 

其中每个单元格代表一个候选名称和时间戳(不断增加并且不断添加新记录)。这个数组可以有数百万条记录。

编写一个函数 findWinner(arr, timestamp) 返回获胜者的姓名直到该时间戳,给定的时间戳可能在给定的数组中,也可能不在给定的数组中。对于领带打印“tie”

我的方法:

方法一:

a. Create a function voteCount(mydict, a) which takes an entry a and stores the count of each candidate in a dictionary and returns a dictionary say mydict
b. Create a function getMax(mydict) which takes the dictionary mydict created and sorts the dictionary with respect to values(count here), checks if there is a repeat (names) with respect to max as one edge case and print out "tie" or prints out the name of the max candidate
c. Create a function findWinner(arr, timestamp) which takes the input array arr, and a given timestamp and iterate through each entry in the array untill the given timestamp and take the name arr[i][0] and call voteCount(mydict, arr[i][0]) on it. 
d. After the loop finishes run getMax on mydict and print out the results

I was thinking of memoization in this scenario because there was no space constraints

方法二:

a. Create a datastructure Node with a name and count like the one below:

class Node
 attr_accessor :name, :count
 def initialize(name,count)
  @name = name
  @count = count
 end
end
b. In the getMax(mydict), take each key value pair as a node in a heap and run a max-heapify function with node.count and print out the root name(For edge case of tie, we can check with root's left child and right child)

【问题讨论】:

  • 您能否将代码附加到向数组添加新项目的过程中?
  • @hatchet:嘿! :) 面试官没这么说,他直接问数据是不是这样给出的,你会怎么处理这个问题。
  • 什么是赢家?数组中的每个元素是否代表一票,以及投票的时间?如果在被查询的时间点有平局怎么办?
  • @hatchet 获胜者是从开始到给定输入时间之前投票数最多的人,其中输入数组中的每个单元格代表一个投票(名称,时间戳)并且时间戳不断增加。正如我已经在我的方法中指定的那样,如果是领带,我们可以打印“领带”,否则打印候选人的姓名
  • 高效解决是什么意思?如果函数只被调用一次或被多次调用,有效的解决方案是不同的。此外,候选人的数量是否有限且事先已知?另外,同时添加记录是什么意思?它们被添加到哪里?输入实际上是如何组织的?时间戳参数是当前时间戳,所以我们只对当前结果感兴趣,还是对以前的结果也感兴趣?

标签: algorithm sorting dictionary time-complexity memoization


【解决方案1】:

创建SortedMap<Integer, Set<String>>(例如红黑树),其中键是时间戳,值是该时间戳的获胜者姓名。还要创建一个Map<String, Integer>,其中键是名称,值是分数(初始化为零)。接下来,遍历数组:

SortedMap<Integer, Set<String>> timestampMap = new RedBlackTree()
Map<String, Integer> scoreMap = new HashMap()
Set<String> currentWinners

foreach [name, timestamp] in array {
  int currentNameScore = scoreMap.get(name) + 1
  scoreMap.put(name, currentNameScore)
  int currentWinnerScore = scoreMap.get(currentWinners.first())
  if(currentWinners.contains(name) || currentNameScore > currentWinnerScore) {
    currentWinners = new Set(name)
  } else if(currentWinnerScore == currentNameScore) {
    currentWinners = currentWinners.copy().add(name)
  }
  timestampMap.put(timestamp, currentWinners)
}

您使用Map 跟踪每个名字的当前分数,然后确定该名字的分数现在是否等于或超过当前获胜者的分数。查询SortedMap 以获取给定的时间戳(如果给定的键不存在,则查询前一个时间戳)是一个 O(log(n)) 操作。 (参见 SortedMap 作为对 SortedMap 的典型操作的示例)初始化 SortedMap 是一个 O(n * log(n)) 操作,所以只有在你是对数据进行多次查询(否则您的线性搜索会更快)。

【讨论】:

  • 我正在写一个答案,但它与您的非常相似,现在将是重复的。主要区别在于获胜者地图只需要在获胜者与其先前值发生变化的点处记录获胜者。在平局的情况下,所有需要注意的是“平局”,而不是获胜者名单(根据 OP 的说明)。
  • @hatchet 我没有看到他的解释——在那种情况下,SortedMap&lt;Integer, Set&lt;String&gt;&gt; 只是SortedMap&lt;Integer, String&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-10-13
  • 1970-01-01
  • 1970-01-01
  • 2020-09-29
  • 2020-03-06
相关资源
最近更新 更多