尽可能放置最接近的学生

时间:2017-08-17 12:28:55

标签: algorithm data-structures

您负责一个单行n个座位的教室,编号为0n-1 白天,学生进入和离开教室参加考试。 为了尽量减少作弊,您的任务是有效地安排所有入学的学生。

您有两种类型的查询:add_student(student_id) -> seat indexremove_student(student_id) -> void

学生座位规则如下:

  1. 座位必须空置
  2. 最亲密的学生必须尽可能远离
  3. 可以通过选择编号最小的座位来解决问题。
  4. 我的方法是使用Hashtable,考虑到我们必须为每个学生分配座位索引,我们可以使用哈希函数。这种方法是否正确?

    如果哈希表是正确的方法,那么 - '最接近的学生必须尽可能远',我该如何设计有效的哈希函数?

    有没有更好的方法来解决这个问题?

2 个答案:

答案 0 :(得分:0)

对我来说,这似乎是一个有趣的问题,所以这里有一个我想出来的算法。

正如问题所说,它只有一行编号从1到n。

我在想这个问题的贪婪方法。

所以这就是它。

  • 首先出席的人将坐在1。
  • 第二个人将坐在n,因为这将创造他们之间最远的距离。
  • 现在我们开始保留子集,因此我们有一个子集为(1,n)。
  • 现在当第三个人进来时,他坐在第一个子集的中间,即(1 + n)/ 2。在此之后,我们将有两个子集 - (1,n / 2)和(n / 2,n)。
  • 现在当第四个人到达时,他可以坐在(1,n / 2)和(n / 2,n)中间。

这一流将继续下去。

  • 现在假设当一个人离开座位并离开课堂时,我们的子集范围将会改变,然后对于下一个进入的人,我们将为他计算新的子集。

希望这会有所帮助。对于这种方法,我认为大小为n的数组也可以很好地工作。

答案 1 :(得分:0)

更新:此解决方案不起作用,因为学生可以离开并打开空白。

所以这就是我提出的解决方案。我会创建一个初始位置数组。所以即将到来的学生的位置只是位置[current_number_of_students-1]。

创建数组是一个棘手的部分。

def position(number_of_chairs)
  # handle edge cases
  return [] if number_of_chairs.nil? || number_of_chairs <= 0
  return [0] if number_of_chairs == 1

  # initialize with first chair and the last chair
  @position = [0, number_of_chairs - 1]

  # We want to start adding the middle of row segments
  # but in the correct order.
  # The first segment is going to be the entire row
  @segments = [0, number_of_chairs - 1]

  while !@segments.empty?
    current_segment = @segments.shift
    mid = (current_segment[0] + current_segment[1]) / 2
    if (mid > current_segment[0] && mid < current_segment[1])
      @position << mid
      # add the bottom half to the queue
      @segments.push([current_segment[0], mid])
      # add the top half to the queue
      @segments.push([mid, current_segment[1]])
    end
  end

  @position
end