这个问题是在一家大型软件公司中提出的。我想出了一个简单的解决方案,并想知道其他人对这个解决方案的感受。
你需要设计一个API和后端系统,用于为城市居民分配电话号码。电话号码将从111-111-1111开始,到999-999-9999结束。API应使客户(城市中的人)能够执行以下操作:
- 当客户请求电话号码时,给他们分配其中一个可用的号码。
- 有些客户可能想要特殊号码,因此他们可以明确要求分配给他们一个号码。如果所请求的号码可用,则将其分配给客户,否则系统将分配任何可用号码。
系统不必知道分配给哪个客户哪个号码。同一客户可能会连续发出请求并为自己获得多个电话号码,但系统不介意。在任何时候,系统只知道哪些电话号码已经被分配,哪些电话号码是空闲的。
从111-111-1111到999-999-9999的号码大约对应于80亿个数字。假设内存不是限制因素,我可以想到以下两种方法(它们几乎相似)。
维护一个巨大的长度为80亿的布尔数组,并具有指向数组索引位置的
next
指针(next
初始化为零)。如果next
指向的值不是空闲的,则将next
前进,直到找到一个空闲的数字。当请求特殊号码时,只需检查相应的索引位置是否为空闲,并返回号码。这种方法的缺点是,在按常规方式分配号码时,如果在中间有巨大的块(例如10亿个)的号码是通过特殊分配分配的,则必须移动1亿次next
指针。 为了克服以前设计中提到的困难,我们可以使用某种链式哈希表。我们维护一个双向链表(这取代了以前设计中的数组)和另一个与列表长度相同的数组,其中数组的每个元素指向列表中的相应元素。因此,在常规方法中分配数字时,我们推进链接列表中的指针,并在分配时标记节点(与先前的方法相同)。当分配花哨的数字时,我们可以直接找到对应于所请求的特殊数字的列表中的节点,方法是首先对数组进行索引,然后按照指针进行跟踪。一旦确定了节点,就要短路上一个节点和下一个节点,这样当进行常规分配时,就不必逐个跳过已使用的数字(这是以前方法的问题)。
请让我知道我是否正确。如果我漏掉了任何重要细节,请告诉我。