โ† All problems

3508. Implement Router

MediumOpen on LeetCodeProblem statement

Problem Statement

3508. Implement Router

Medium


Design a data structure that can efficiently manage data packets in a network router. Each data packet consists of the following attributes:

Implement the Router class:

Router(int memoryLimit): Initializes the Router object with a fixed memory limit.

bool addPacket(int source, int destination, int timestamp): Adds a packet with the given attributes to the router.

int[] forwardPacket(): Forwards the next packet in FIFO (First In First Out) order.

int getCount(int destination, int startTime, int endTime):

Note that queries for addPacket will be made in increasing order of timestamp.

 

Example 1:

Input:
["Router", "addPacket", "addPacket", "addPacket", "addPacket", "addPacket", "forwardPacket", "addPacket", "getCount"]
[[3], [1, 4, 90], [2, 5, 90], [1, 4, 90], [3, 5, 95], [4, 5, 105], [], [5, 2, 110], [5, 100, 110]]

Output:
[null, true, true, false, true, true, [2, 5, 90], true, 1]

Explanation

Router router = new Router(3); // Initialize Router with memoryLimit of 3.
router.addPacket(1, 4, 90); // Packet is added. Return True.
router.addPacket(2, 5, 90); // Packet is added. Return True.
router.addPacket(1, 4, 90); // This is a duplicate packet. Return False.
router.addPacket(3, 5, 95); // Packet is added. Return True
router.addPacket(4, 5, 105); // Packet is added, [1, 4, 90] is removed as number of packets exceeds memoryLimit. Return True.
router.forwardPacket(); // Return [2, 5, 90] and remove it from router.
router.addPacket(5, 2, 110); // Packet is added. Return True.
router.getCount(5, 100, 110); // The only packet with destination 5 and timestamp in the inclusive range [100, 110] is [4, 5, 105]. Return 1.

Example 2:

Input:
["Router", "addPacket", "forwardPacket", "forwardPacket"]
[[2], [7, 4, 90], [], []]

Output:
[null, true, [7, 4, 90], []]

Explanation

Router router = new Router(2); // Initialize Router with memoryLimit of 2.
router.addPacket(7, 4, 90); // Return True.
router.forwardPacket(); // Return [7, 4, 90].
router.forwardPacket(); // There are no packets left, return [].

 

Constraints:

Java โ€” myDesign TLE

Source file
public class Packet {
    int src;
    int dest;
    int tsp;

    public Packet(int source, int destination, int timestamp) {
        src = source;
        dest = destination;
        tsp = timestamp;
    }

    @Override
    public boolean equals(Object other) {
        Packet o = (Packet) other;
        return this.src == o.src && this.dest == o.dest && this.tsp == o.tsp;
    }

    @Override
    public int hashCode() {
        return Objects.hash(src, dest, tsp);
    }
}

class Router {
    int memCap;
    LinkedHashSet<Packet> q;
    TreeMap<Integer, Map<Integer, Integer>> tspBasedDestMap;

    public Router(int memoryLimit) {
        q = new LinkedHashSet<>();
        tspBasedDestMap = new TreeMap<>();
        memCap = memoryLimit;
    }

    public boolean addPacket(int source, int destination, int timestamp) {
        Packet newPacket = new Packet(source, destination, timestamp);
        if (q.contains(newPacket))
            return false;
        if (q.size() == memCap) {
            Iterator<Packet> it = q.iterator();
            Packet top = it.next();
            int newCt = tspBasedDestMap.get(top.tsp).get(top.dest) - 1;
            if (newCt == 0)
                tspBasedDestMap.get(top.tsp).remove(top.dest);
            else
                tspBasedDestMap.get(top.tsp).put(top.dest, newCt);
            it.remove();
        }
        q.add(newPacket);
        tspBasedDestMap.putIfAbsent(timestamp, new HashMap<>());
        tspBasedDestMap.get(timestamp).put(destination,
                tspBasedDestMap.get(timestamp).getOrDefault(destination, 0) + 1);
        return true;
    }

    public int[] forwardPacket() {
        if (q.isEmpty())
            return new int[0];
        Iterator<Packet> it = q.iterator();
        Packet top = it.next();
        int newCt = tspBasedDestMap.get(top.tsp).get(top.dest) - 1;
        if (newCt == 0)
            tspBasedDestMap.get(top.tsp).remove(top.dest);
        else
            tspBasedDestMap.get(top.tsp).put(top.dest, newCt);
        it.remove();
        return new int[] { top.src, top.dest, top.tsp };
    }

    public int getCount(int destination, int startTime, int endTime) {
        int matchCount = 0;
        NavigableMap<Integer, Map<Integer, Integer>> tailMap = tspBasedDestMap.tailMap(startTime, true);
        for (Map.Entry<Integer, Map<Integer, Integer>> e : tailMap.entrySet()) {
            if (e.getKey() > endTime)
                break;
            matchCount += e.getValue().getOrDefault(destination, 0);
        }
        return matchCount;
    }
}

/**
 * Your Router object will be instantiated and called as such:
 * Router obj = new Router(memoryLimit);
 * boolean param_1 = obj.addPacket(source,destination,timestamp);
 * int[] param_2 = obj.forwardPacket();
 * int param_3 = obj.getCount(destination,startTime,endTime);
 */