Skip to content

Commit f529f97

Browse files
committed
Add solution #3508
1 parent 01e63c9 commit f529f97

File tree

2 files changed

+167
-0
lines changed

2 files changed

+167
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2763,6 +2763,7 @@
27632763
3495|[Minimum Operations to Make Array Elements Zero](./solutions/3495-minimum-operations-to-make-array-elements-zero.js)|Hard|
27642764
3496|[Maximize Score After Pair Deletions](./solutions/3496-maximize-score-after-pair-deletions.js)|Medium|
27652765
3506|[Find Time Required to Eliminate Bacterial Strains](./solutions/3506-find-time-required-to-eliminate-bacterial-strains.js)|Hard|
2766+
3508|[Implement Router](./solutions/3508-implement-router.js)|Medium|
27662767
3511|[Make a Positive Array](./solutions/3511-make-a-positive-array.js)|Medium|
27672768
3516|[Find Closest Person](./solutions/3516-find-closest-person.js)|Easy|
27682769
3520|[Minimum Threshold for Inversion Pairs Count](./solutions/3520-minimum-threshold-for-inversion-pairs-count.js)|Medium|

solutions/3508-implement-router.js

Lines changed: 166 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,166 @@
1+
/**
2+
* 3508. Implement Router
3+
* https://leetcode.com/problems/implement-router/
4+
* Difficulty: Medium
5+
*
6+
* Design a data structure that can efficiently manage data packets in a network router.
7+
* Each data packet consists of the following attributes:
8+
* - source: A unique identifier for the machine that generated the packet.
9+
* - destination: A unique identifier for the target machine.
10+
* - timestamp: The time at which the packet arrived at the router.
11+
*
12+
* Implement the Router class:
13+
* Router(int memoryLimit): Initializes the Router object with a fixed memory limit.
14+
* - memoryLimit is the maximum number of packets the router can store at any given time.
15+
* - If adding a new packet would exceed this limit, the oldest packet must be removed to
16+
* free up space.
17+
* bool addPacket(int source, int destination, int timestamp): Adds a packet with the
18+
* given attributes to the router.
19+
* - A packet is considered a duplicate if another packet with the same source, destination,
20+
* and timestamp already exists in the router.
21+
* - Return true if the packet is successfully added (i.e., it is not a duplicate); otherwise
22+
* return false.
23+
* int[] forwardPacket(): Forwards the next packet in FIFO (First In First Out) order.
24+
* - Remove the packet from storage.
25+
* - Return the packet as an array [source, destination, timestamp].
26+
* - If there are no packets to forward, return an empty array.
27+
* int getCount(int destination, int startTime, int endTime):
28+
* - Returns the number of packets currently stored in the router (i.e., not yet forwarded) that
29+
* have the specified destination and have timestamps in the inclusive range [startTime, endTime].
30+
*
31+
* Note that queries for addPacket will be made in increasing order of timestamp.
32+
*/
33+
34+
/**
35+
* @param {number} memoryLimit
36+
*/
37+
var Router = function(memoryLimit) {
38+
this.memoryCapacity = memoryLimit;
39+
this.packetQueue = [];
40+
this.packetSet = new Set();
41+
this.destinationTimestamps = new Map();
42+
this.removedPacketIndex = new Map();
43+
};
44+
45+
/**
46+
* @param {number} source
47+
* @param {number} destination
48+
* @param {number} timestamp
49+
* @return {boolean}
50+
*/
51+
Router.prototype.addPacket = function(source, destination, timestamp) {
52+
const packetKey = `${source}-${destination}-${timestamp}`;
53+
54+
if (this.packetSet.has(packetKey)) {
55+
return false;
56+
}
57+
58+
if (this.packetQueue.length === this.memoryCapacity) {
59+
const [oldSource, oldDestination, oldTimestamp] = this.packetQueue.shift();
60+
const oldPacketKey = `${oldSource}-${oldDestination}-${oldTimestamp}`;
61+
this.packetSet.delete(oldPacketKey);
62+
this.removedPacketIndex.set(
63+
oldDestination,
64+
(this.removedPacketIndex.get(oldDestination) || 0) + 1,
65+
);
66+
}
67+
68+
this.packetQueue.push([source, destination, timestamp]);
69+
this.packetSet.add(packetKey);
70+
71+
if (!this.destinationTimestamps.has(destination)) {
72+
this.destinationTimestamps.set(destination, []);
73+
}
74+
this.destinationTimestamps.get(destination).push(timestamp);
75+
76+
return true;
77+
};
78+
79+
/**
80+
* @return {number[]}
81+
*/
82+
Router.prototype.forwardPacket = function() {
83+
if (this.packetQueue.length === 0) {
84+
return [];
85+
}
86+
87+
const [source, destination, timestamp] = this.packetQueue.shift();
88+
const packetKey = `${source}-${destination}-${timestamp}`;
89+
this.packetSet.delete(packetKey);
90+
this.removedPacketIndex.set(destination, (this.removedPacketIndex.get(destination) || 0) + 1);
91+
92+
return [source, destination, timestamp];
93+
};
94+
95+
/**
96+
* @param {number} destination
97+
* @param {number} startTime
98+
* @param {number} endTime
99+
* @return {number}
100+
*/
101+
Router.prototype.getCount = function(destination, startTime, endTime) {
102+
if (!this.destinationTimestamps.has(destination)) {
103+
return 0;
104+
}
105+
106+
const timestampArray = this.destinationTimestamps.get(destination);
107+
const removedCount = this.removedPacketIndex.get(destination) || 0;
108+
const totalLength = timestampArray.length;
109+
110+
if (removedCount >= totalLength) {
111+
return 0;
112+
}
113+
114+
const leftBound = this.binarySearchLeft(timestampArray, startTime, removedCount);
115+
const rightBound = this.binarySearchRight(timestampArray, endTime, removedCount) - 1;
116+
117+
if (leftBound > rightBound) {
118+
return 0;
119+
}
120+
121+
return rightBound - leftBound + 1;
122+
};
123+
124+
/**
125+
* @param {number[]} array
126+
* @param {number} target
127+
* @param {number} startIndex
128+
* @return {number}
129+
*/
130+
Router.prototype.binarySearchLeft = function(array, target, startIndex) {
131+
let left = startIndex;
132+
let right = array.length;
133+
134+
while (left < right) {
135+
const mid = Math.floor((left + right) / 2);
136+
if (array[mid] < target) {
137+
left = mid + 1;
138+
} else {
139+
right = mid;
140+
}
141+
}
142+
143+
return left;
144+
};
145+
146+
/**
147+
* @param {number[]} array
148+
* @param {number} target
149+
* @param {number} startIndex
150+
* @return {number}
151+
*/
152+
Router.prototype.binarySearchRight = function(array, target, startIndex) {
153+
let left = startIndex;
154+
let right = array.length;
155+
156+
while (left < right) {
157+
const mid = Math.floor((left + right) / 2);
158+
if (array[mid] <= target) {
159+
left = mid + 1;
160+
} else {
161+
right = mid;
162+
}
163+
}
164+
165+
return left;
166+
};

0 commit comments

Comments
 (0)