379. Design Phone Directory

379. Design Phone Directory

Design a Phone Directory which supports the following operations:

  1. get: Provide a number which is not assigned to anyone.
  2. check: Check if a number is available or not.
  3. release: Recycle or release a number.

Example:

// Init a phone directory containing a total of 3 numbers: 0, 1, and 2.
PhoneDirectory directory = new PhoneDirectory(3);

// It can return any available phone number. Here we assume it returns 0.
directory.get();

// Assume it returns 1.
directory.get();

// The number 2 is available, so return true.
directory.check(2);

// It returns 2, the only number that is left.
directory.get();

// The number 2 is no longer available, so return false.
directory.check(2);

// Release number 2 back to the pool.
directory.release(2);

// Number 2 is available again, return true.
directory.check(2);

State the problem (as you understand it):

Solve examples that are big enough and are not special cases (manually to figure out the general solution): 

Ask clarification questions:

  1. what is the frequency of get() and release() calls?
  2. optimize for time or space?

State assumptions:

  1. get() and release() calls happen at the same frequency

Consider several test cases (edge cases, base cases):

See if a Data Structure fits the problem:

See if an Algorithm fits the problem:

Extract the core problem:

Try breaking it down into subproblems:

Explain Potential Solutions (see solutin section):

Other solutions:

Compare solutions:

Follow Up (TODO):

  1. how scalable this solution is if we are talking about 10 digit real phone number?
    1. probably expect some discussion of distributed hash tables
  2. what happens if it is being used in multithreaded situation?

Solution 1:


Ideas: 

  1. not necessary to store both used and unused numbers, just keep track of the unused ones to save memory
  2. keep track of the largest number offered so far to avoid O(n) initialization for available numbers. Anything above the largest number offered so far is available for offering 
  3. exhaust the sparse set of available numbers first if it's not empty

Steps:

Validate the correctness (of your pseudocode with a test case):

Data Structure:

Time Complexity:

Space Complexity:

public class PhoneDirectory {
    private final Set<Integer> available = new LinkedHashSet<>();
    private final int maxNumbers;
    private int largestOffered = -1;
 
    public PhoneDirectory(int maxNumbers) {
        this.maxNumbers = maxNumbers;
    }
 
    public int get() {
        if (this.available.isEmpty()) {
            return this.largestOffered < this.maxNumbers - 1 ? (++this.largestOffered) : -1;
        }
 
        Iterator<Integer> iterator = this.available.iterator();
        int res = iterator.next();
        iterator.remove();
        return res;
    }
    
    public boolean check(int number) {
        return this.available.contains(number) || number > this.largestOffered && number < this.maxNumbers;
    }
 
    public void release(int number) {
        if (number <= this.largestOffered) {
            this.available.add(number);
        }
    }
}

Test your code again to make sure you don't have any bugs.

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值