-3

To design a API,

  1. get(), it will return the random number, also the number should not duplicate, means it always be unique.
  2. put(randomvalue), it will put back the generated random number from get(), if put back, get() function can reuse this number as output.

It has to be efficient, no too much resource is highly used.

Is there any way to implement this algorithm? It is not recommended to use hashmap, because if this API generate for billions of requests, saving the generated the random number still use too much space.

I could no work out this algorithm, please help give a clue, thanks in advance!

Igor F.
  • 2,649
  • 2
  • 31
  • 39
  • 1
    Which language u r using and what are ur efforts? – Shankar Saran Singh Nov 19 '19 at 07:50
  • If you don't use a map or a set, how can you ensure that a number is not generated twice? – Maurice Perry Nov 19 '19 at 07:53
  • You could try to store the random numbers that were already chosen in a [TreeSet](https://docs.oracle.com/javase/7/docs/api/java/util/TreeSet.html) (from javadoc: `This implementation provides guaranteed log(n) time cost for the basic operations (add, remove and contains).`). So it's quite time efficient and also much more space efficient than a `HashMap`. – Tobias Nov 19 '19 at 07:58
  • 1
    Is this an exam question, or similar? For real-world purposes I see no reason why you'd need the `put()` function. Simply ignore the numbers which have become obsolete. – Igor F. Nov 19 '19 at 08:01
  • 3
    Use a [linear congruential generator](https://en.wikipedia.org/wiki/Linear_congruential_generator) with a period of 2^64. Even with a billion `get()` requests per second, it'll be over 500 years before a number is repeated. The `put()` request is a [no-op](https://en.wikipedia.org/wiki/NOP_(code)), just ignore it. The statement that you *"can reuse this number"* doesn't mean that you *"have to reuse this number"*. – user3386109 Nov 19 '19 at 08:15

1 Answers1

0

I cannot think of any solution without extra space. With space, one option could be to use TreeMap, firstly add all the elements in treeMap with as false. When element is accessed, mark as true. Similarly for put, change the value to false. Code snippet below...

public class RandomNumber {

public static final int SIZE = 100000;
public static Random rand;
public static TreeMap<Integer, Boolean> treeMap;

public RandomNumber() {
    rand = new Random();
    treeMap = new TreeMap<>();
}

static public int getRandom() {
    while (true) {
        int random = rand.nextInt(SIZE);
        if (!treeMap.get(random)) {
            treeMap.put(random, true);
            return random;
        }
    }
}

static public void putRandom(int number) {
    treeMap.put(number, false);
}
}
Srikanth Hugar
  • 385
  • 5
  • 22