diff --git a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/README.md b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/README.md index 6358298483bda..bfc18258ddd42 100644 --- a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/README.md +++ b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/README.md @@ -87,18 +87,18 @@ class Solution: self, chargeTimes: List[int], runningCosts: List[int], budget: int ) -> int: q = deque() - ans = j = s = 0 - for i, (a, b) in enumerate(zip(chargeTimes, runningCosts)): - while q and chargeTimes[q[-1]] <= a: + ans = s = l = 0 + for r, (t, c) in enumerate(zip(chargeTimes, runningCosts)): + s += c + while q and chargeTimes[q[-1]] <= t: q.pop() - q.append(i) - s += b - while q and chargeTimes[q[0]] + (i - j + 1) * s > budget: - if q[0] == j: + q.append(r) + while q and (r - l + 1) * s + chargeTimes[q[0]] > budget: + if q[0] == l: q.popleft() - s -= runningCosts[j] - j += 1 - ans = max(ans, i - j + 1) + s -= runningCosts[l] + l += 1 + ans = max(ans, r - l + 1) return ans ``` @@ -109,23 +109,21 @@ class Solution { public int maximumRobots(int[] chargeTimes, int[] runningCosts, long budget) { Deque q = new ArrayDeque<>(); int n = chargeTimes.length; - long s = 0; - int j = 0; int ans = 0; - for (int i = 0; i < n; ++i) { - int a = chargeTimes[i], b = runningCosts[i]; - while (!q.isEmpty() && chargeTimes[q.getLast()] <= a) { + long s = 0; + for (int l = 0, r = 0; r < n; ++r) { + s += runningCosts[r]; + while (!q.isEmpty() && chargeTimes[q.peekLast()] <= chargeTimes[r]) { q.pollLast(); } - q.offer(i); - s += b; - while (!q.isEmpty() && chargeTimes[q.getFirst()] + (i - j + 1) * s > budget) { - if (q.getFirst() == j) { + q.offerLast(r); + while (!q.isEmpty() && (r - l + 1) * s + chargeTimes[q.peekFirst()] > budget) { + if (q.peekFirst() == l) { q.pollFirst(); } - s -= runningCosts[j++]; + s -= runningCosts[l++]; } - ans = Math.max(ans, i - j + 1); + ans = Math.max(ans, r - l + 1); } return ans; } @@ -140,19 +138,21 @@ public: int maximumRobots(vector& chargeTimes, vector& runningCosts, long long budget) { deque q; long long s = 0; - int ans = 0, j = 0, n = chargeTimes.size(); - for (int i = 0; i < n; ++i) { - int a = chargeTimes[i], b = runningCosts[i]; - while (!q.empty() && chargeTimes[q.back()] <= a) q.pop_back(); - q.push_back(i); - s += b; - while (!q.empty() && chargeTimes[q.front()] + (i - j + 1) * s > budget) { - if (q.front() == j) { + int ans = 0; + int n = chargeTimes.size(); + for (int l = 0, r = 0; r < n; ++r) { + s += runningCosts[r]; + while (q.size() && chargeTimes[q.back()] <= chargeTimes[r]) { + q.pop_back(); + } + q.push_back(r); + while (q.size() && (r - l + 1) * s + chargeTimes[q.front()] > budget) { + if (q.front() == l) { q.pop_front(); } - s -= runningCosts[j++]; + s -= runningCosts[l++]; } - ans = max(ans, i - j + 1); + ans = max(ans, r - l + 1); } return ans; } @@ -162,26 +162,205 @@ public: #### Go ```go -func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) int { +func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) (ans int) { + q := Deque{} s := int64(0) - ans, j := 0, 0 - q := []int{} - for i, a := range chargeTimes { - for len(q) > 0 && chargeTimes[q[len(q)-1]] <= a { - q = q[:len(q)-1] + l := 0 + for r, t := range chargeTimes { + s += int64(runningCosts[r]) + for !q.Empty() && chargeTimes[q.Back()] <= t { + q.PopBack() } - q = append(q, i) - s += int64(runningCosts[i]) - for len(q) > 0 && int64(chargeTimes[q[0]])+int64(i-j+1)*s > budget { - if q[0] == j { - q = q[1:] + q.PushBack(r) + for !q.Empty() && int64(r-l+1)*s+int64(chargeTimes[q.Front()]) > budget { + if q.Front() == l { + q.PopFront() } - s -= int64(runningCosts[j]) - j++ + s -= int64(runningCosts[l]) + l++ } - ans = max(ans, i-j+1) + ans = max(ans, r-l+1) } - return ans + return +} + +// template +type Deque struct{ l, r []int } + +func (q Deque) Empty() bool { + return len(q.l) == 0 && len(q.r) == 0 +} + +func (q Deque) Size() int { + return len(q.l) + len(q.r) +} + +func (q *Deque) PushFront(v int) { + q.l = append(q.l, v) +} + +func (q *Deque) PushBack(v int) { + q.r = append(q.r, v) +} + +func (q *Deque) PopFront() (v int) { + if len(q.l) > 0 { + q.l, v = q.l[:len(q.l)-1], q.l[len(q.l)-1] + } else { + v, q.r = q.r[0], q.r[1:] + } + return +} + +func (q *Deque) PopBack() (v int) { + if len(q.r) > 0 { + q.r, v = q.r[:len(q.r)-1], q.r[len(q.r)-1] + } else { + v, q.l = q.l[0], q.l[1:] + } + return +} + +func (q Deque) Front() int { + if len(q.l) > 0 { + return q.l[len(q.l)-1] + } + return q.r[0] +} + +func (q Deque) Back() int { + if len(q.r) > 0 { + return q.r[len(q.r)-1] + } + return q.l[0] +} + +func (q Deque) Get(i int) int { + if i < len(q.l) { + return q.l[len(q.l)-1-i] + } + return q.r[i-len(q.l)] +} +``` + +#### TypeScript + +```ts +function maximumRobots(chargeTimes: number[], runningCosts: number[], budget: number): number { + const q = new Deque(); + const n = chargeTimes.length; + let [ans, s] = [0, 0]; + for (let l = 0, r = 0; r < n; ++r) { + s += runningCosts[r]; + while (!q.isEmpty() && chargeTimes[q.backValue()!] <= chargeTimes[r]) { + q.popBack(); + } + q.pushBack(r); + while (!q.isEmpty() && (r - l + 1) * s + chargeTimes[q.frontValue()!] > budget) { + if (q.frontValue() === l) { + q.popFront(); + } + s -= runningCosts[l++]; + } + ans = Math.max(ans, r - l + 1); + } + return ans; +} + +class Node { + value: T; + next: Node | null; + prev: Node | null; + + constructor(value: T) { + this.value = value; + this.next = null; + this.prev = null; + } +} + +class Deque { + private front: Node | null; + private back: Node | null; + private size: number; + + constructor() { + this.front = null; + this.back = null; + this.size = 0; + } + + pushFront(val: T): void { + const newNode = new Node(val); + if (this.isEmpty()) { + this.front = newNode; + this.back = newNode; + } else { + newNode.next = this.front; + this.front!.prev = newNode; + this.front = newNode; + } + this.size++; + } + + pushBack(val: T): void { + const newNode = new Node(val); + if (this.isEmpty()) { + this.front = newNode; + this.back = newNode; + } else { + newNode.prev = this.back; + this.back!.next = newNode; + this.back = newNode; + } + this.size++; + } + + popFront(): T | undefined { + if (this.isEmpty()) { + return undefined; + } + const value = this.front!.value; + this.front = this.front!.next; + if (this.front !== null) { + this.front.prev = null; + } else { + this.back = null; + } + this.size--; + return value; + } + + popBack(): T | undefined { + if (this.isEmpty()) { + return undefined; + } + const value = this.back!.value; + this.back = this.back!.prev; + if (this.back !== null) { + this.back.next = null; + } else { + this.front = null; + } + this.size--; + return value; + } + + frontValue(): T | undefined { + return this.front?.value; + } + + backValue(): T | undefined { + return this.back?.value; + } + + getSize(): number { + return this.size; + } + + isEmpty(): boolean { + return this.size === 0; + } } ``` diff --git a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/README_EN.md b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/README_EN.md index 56b1fcb9007b6..4f5caba26b5b0 100644 --- a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/README_EN.md +++ b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/README_EN.md @@ -35,7 +35,7 @@ tags:
 Input: chargeTimes = [3,6,1,3,4], runningCosts = [2,1,3,4,5], budget = 25
 Output: 3
-Explanation: 
+Explanation:
 It is possible to run all individual and consecutive pairs of robots within budget.
 To obtain answer 3, consider the first 3 robots. The total cost will be max(3,6,1) + 3 * sum(2,1,3) = 6 + 3 * 6 = 24 which is less than 25.
 It can be shown that it is not possible to run more than 3 consecutive robots within budget, so we return 3.
@@ -85,18 +85,18 @@ class Solution:
         self, chargeTimes: List[int], runningCosts: List[int], budget: int
     ) -> int:
         q = deque()
-        ans = j = s = 0
-        for i, (a, b) in enumerate(zip(chargeTimes, runningCosts)):
-            while q and chargeTimes[q[-1]] <= a:
+        ans = s = l = 0
+        for r, (t, c) in enumerate(zip(chargeTimes, runningCosts)):
+            s += c
+            while q and chargeTimes[q[-1]] <= t:
                 q.pop()
-            q.append(i)
-            s += b
-            while q and chargeTimes[q[0]] + (i - j + 1) * s > budget:
-                if q[0] == j:
+            q.append(r)
+            while q and (r - l + 1) * s + chargeTimes[q[0]] > budget:
+                if q[0] == l:
                     q.popleft()
-                s -= runningCosts[j]
-                j += 1
-            ans = max(ans, i - j + 1)
+                s -= runningCosts[l]
+                l += 1
+            ans = max(ans, r - l + 1)
         return ans
 ```
 
@@ -107,23 +107,21 @@ class Solution {
     public int maximumRobots(int[] chargeTimes, int[] runningCosts, long budget) {
         Deque q = new ArrayDeque<>();
         int n = chargeTimes.length;
-        long s = 0;
-        int j = 0;
         int ans = 0;
-        for (int i = 0; i < n; ++i) {
-            int a = chargeTimes[i], b = runningCosts[i];
-            while (!q.isEmpty() && chargeTimes[q.getLast()] <= a) {
+        long s = 0;
+        for (int l = 0, r = 0; r < n; ++r) {
+            s += runningCosts[r];
+            while (!q.isEmpty() && chargeTimes[q.peekLast()] <= chargeTimes[r]) {
                 q.pollLast();
             }
-            q.offer(i);
-            s += b;
-            while (!q.isEmpty() && chargeTimes[q.getFirst()] + (i - j + 1) * s > budget) {
-                if (q.getFirst() == j) {
+            q.offerLast(r);
+            while (!q.isEmpty() && (r - l + 1) * s + chargeTimes[q.peekFirst()] > budget) {
+                if (q.peekFirst() == l) {
                     q.pollFirst();
                 }
-                s -= runningCosts[j++];
+                s -= runningCosts[l++];
             }
-            ans = Math.max(ans, i - j + 1);
+            ans = Math.max(ans, r - l + 1);
         }
         return ans;
     }
@@ -138,19 +136,21 @@ public:
     int maximumRobots(vector& chargeTimes, vector& runningCosts, long long budget) {
         deque q;
         long long s = 0;
-        int ans = 0, j = 0, n = chargeTimes.size();
-        for (int i = 0; i < n; ++i) {
-            int a = chargeTimes[i], b = runningCosts[i];
-            while (!q.empty() && chargeTimes[q.back()] <= a) q.pop_back();
-            q.push_back(i);
-            s += b;
-            while (!q.empty() && chargeTimes[q.front()] + (i - j + 1) * s > budget) {
-                if (q.front() == j) {
+        int ans = 0;
+        int n = chargeTimes.size();
+        for (int l = 0, r = 0; r < n; ++r) {
+            s += runningCosts[r];
+            while (q.size() && chargeTimes[q.back()] <= chargeTimes[r]) {
+                q.pop_back();
+            }
+            q.push_back(r);
+            while (q.size() && (r - l + 1) * s + chargeTimes[q.front()] > budget) {
+                if (q.front() == l) {
                     q.pop_front();
                 }
-                s -= runningCosts[j++];
+                s -= runningCosts[l++];
             }
-            ans = max(ans, i - j + 1);
+            ans = max(ans, r - l + 1);
         }
         return ans;
     }
@@ -160,26 +160,205 @@ public:
 #### Go
 
 ```go
-func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) int {
+func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) (ans int) {
+	q := Deque{}
 	s := int64(0)
-	ans, j := 0, 0
-	q := []int{}
-	for i, a := range chargeTimes {
-		for len(q) > 0 && chargeTimes[q[len(q)-1]] <= a {
-			q = q[:len(q)-1]
+	l := 0
+	for r, t := range chargeTimes {
+		s += int64(runningCosts[r])
+		for !q.Empty() && chargeTimes[q.Back()] <= t {
+			q.PopBack()
 		}
-		q = append(q, i)
-		s += int64(runningCosts[i])
-		for len(q) > 0 && int64(chargeTimes[q[0]])+int64(i-j+1)*s > budget {
-			if q[0] == j {
-				q = q[1:]
+		q.PushBack(r)
+		for !q.Empty() && int64(r-l+1)*s+int64(chargeTimes[q.Front()]) > budget {
+			if q.Front() == l {
+				q.PopFront()
 			}
-			s -= int64(runningCosts[j])
-			j++
+			s -= int64(runningCosts[l])
+			l++
 		}
-		ans = max(ans, i-j+1)
+		ans = max(ans, r-l+1)
 	}
-	return ans
+	return
+}
+
+// template
+type Deque struct{ l, r []int }
+
+func (q Deque) Empty() bool {
+	return len(q.l) == 0 && len(q.r) == 0
+}
+
+func (q Deque) Size() int {
+	return len(q.l) + len(q.r)
+}
+
+func (q *Deque) PushFront(v int) {
+	q.l = append(q.l, v)
+}
+
+func (q *Deque) PushBack(v int) {
+	q.r = append(q.r, v)
+}
+
+func (q *Deque) PopFront() (v int) {
+	if len(q.l) > 0 {
+		q.l, v = q.l[:len(q.l)-1], q.l[len(q.l)-1]
+	} else {
+		v, q.r = q.r[0], q.r[1:]
+	}
+	return
+}
+
+func (q *Deque) PopBack() (v int) {
+	if len(q.r) > 0 {
+		q.r, v = q.r[:len(q.r)-1], q.r[len(q.r)-1]
+	} else {
+		v, q.l = q.l[0], q.l[1:]
+	}
+	return
+}
+
+func (q Deque) Front() int {
+	if len(q.l) > 0 {
+		return q.l[len(q.l)-1]
+	}
+	return q.r[0]
+}
+
+func (q Deque) Back() int {
+	if len(q.r) > 0 {
+		return q.r[len(q.r)-1]
+	}
+	return q.l[0]
+}
+
+func (q Deque) Get(i int) int {
+	if i < len(q.l) {
+		return q.l[len(q.l)-1-i]
+	}
+	return q.r[i-len(q.l)]
+}
+```
+
+#### TypeScript
+
+```ts
+function maximumRobots(chargeTimes: number[], runningCosts: number[], budget: number): number {
+    const q = new Deque();
+    const n = chargeTimes.length;
+    let [ans, s] = [0, 0];
+    for (let l = 0, r = 0; r < n; ++r) {
+        s += runningCosts[r];
+        while (!q.isEmpty() && chargeTimes[q.backValue()!] <= chargeTimes[r]) {
+            q.popBack();
+        }
+        q.pushBack(r);
+        while (!q.isEmpty() && (r - l + 1) * s + chargeTimes[q.frontValue()!] > budget) {
+            if (q.frontValue() === l) {
+                q.popFront();
+            }
+            s -= runningCosts[l++];
+        }
+        ans = Math.max(ans, r - l + 1);
+    }
+    return ans;
+}
+
+class Node {
+    value: T;
+    next: Node | null;
+    prev: Node | null;
+
+    constructor(value: T) {
+        this.value = value;
+        this.next = null;
+        this.prev = null;
+    }
+}
+
+class Deque {
+    private front: Node | null;
+    private back: Node | null;
+    private size: number;
+
+    constructor() {
+        this.front = null;
+        this.back = null;
+        this.size = 0;
+    }
+
+    pushFront(val: T): void {
+        const newNode = new Node(val);
+        if (this.isEmpty()) {
+            this.front = newNode;
+            this.back = newNode;
+        } else {
+            newNode.next = this.front;
+            this.front!.prev = newNode;
+            this.front = newNode;
+        }
+        this.size++;
+    }
+
+    pushBack(val: T): void {
+        const newNode = new Node(val);
+        if (this.isEmpty()) {
+            this.front = newNode;
+            this.back = newNode;
+        } else {
+            newNode.prev = this.back;
+            this.back!.next = newNode;
+            this.back = newNode;
+        }
+        this.size++;
+    }
+
+    popFront(): T | undefined {
+        if (this.isEmpty()) {
+            return undefined;
+        }
+        const value = this.front!.value;
+        this.front = this.front!.next;
+        if (this.front !== null) {
+            this.front.prev = null;
+        } else {
+            this.back = null;
+        }
+        this.size--;
+        return value;
+    }
+
+    popBack(): T | undefined {
+        if (this.isEmpty()) {
+            return undefined;
+        }
+        const value = this.back!.value;
+        this.back = this.back!.prev;
+        if (this.back !== null) {
+            this.back.next = null;
+        } else {
+            this.front = null;
+        }
+        this.size--;
+        return value;
+    }
+
+    frontValue(): T | undefined {
+        return this.front?.value;
+    }
+
+    backValue(): T | undefined {
+        return this.back?.value;
+    }
+
+    getSize(): number {
+        return this.size;
+    }
+
+    isEmpty(): boolean {
+        return this.size === 0;
+    }
 }
 ```
 
diff --git a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.cpp b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.cpp
index 0d0984b95cc0f..53fb6441a18dd 100644
--- a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.cpp	
+++ b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.cpp	
@@ -3,20 +3,22 @@ class Solution {
     int maximumRobots(vector& chargeTimes, vector& runningCosts, long long budget) {
         deque q;
         long long s = 0;
-        int ans = 0, j = 0, n = chargeTimes.size();
-        for (int i = 0; i < n; ++i) {
-            int a = chargeTimes[i], b = runningCosts[i];
-            while (!q.empty() && chargeTimes[q.back()] <= a) q.pop_back();
-            q.push_back(i);
-            s += b;
-            while (!q.empty() && chargeTimes[q.front()] + (i - j + 1) * s > budget) {
-                if (q.front() == j) {
+        int ans = 0;
+        int n = chargeTimes.size();
+        for (int l = 0, r = 0; r < n; ++r) {
+            s += runningCosts[r];
+            while (q.size() && chargeTimes[q.back()] <= chargeTimes[r]) {
+                q.pop_back();
+            }
+            q.push_back(r);
+            while (q.size() && (r - l + 1) * s + chargeTimes[q.front()] > budget) {
+                if (q.front() == l) {
                     q.pop_front();
                 }
-                s -= runningCosts[j++];
+                s -= runningCosts[l++];
             }
-            ans = max(ans, i - j + 1);
+            ans = max(ans, r - l + 1);
         }
         return ans;
     }
-};
\ No newline at end of file
+};
diff --git a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.go b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.go
index 25cf292ccdbc2..af33e78fbdc4c 100644
--- a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.go	
+++ b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.go	
@@ -1,21 +1,79 @@
-func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) int {
+func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) (ans int) {
+	q := Deque{}
 	s := int64(0)
-	ans, j := 0, 0
-	q := []int{}
-	for i, a := range chargeTimes {
-		for len(q) > 0 && chargeTimes[q[len(q)-1]] <= a {
-			q = q[:len(q)-1]
+	l := 0
+	for r, t := range chargeTimes {
+		s += int64(runningCosts[r])
+		for !q.Empty() && chargeTimes[q.Back()] <= t {
+			q.PopBack()
 		}
-		q = append(q, i)
-		s += int64(runningCosts[i])
-		for len(q) > 0 && int64(chargeTimes[q[0]])+int64(i-j+1)*s > budget {
-			if q[0] == j {
-				q = q[1:]
+		q.PushBack(r)
+		for !q.Empty() && int64(r-l+1)*s+int64(chargeTimes[q.Front()]) > budget {
+			if q.Front() == l {
+				q.PopFront()
 			}
-			s -= int64(runningCosts[j])
-			j++
+			s -= int64(runningCosts[l])
+			l++
 		}
-		ans = max(ans, i-j+1)
+		ans = max(ans, r-l+1)
 	}
-	return ans
-}
\ No newline at end of file
+	return
+}
+
+// template
+type Deque struct{ l, r []int }
+
+func (q Deque) Empty() bool {
+	return len(q.l) == 0 && len(q.r) == 0
+}
+
+func (q Deque) Size() int {
+	return len(q.l) + len(q.r)
+}
+
+func (q *Deque) PushFront(v int) {
+	q.l = append(q.l, v)
+}
+
+func (q *Deque) PushBack(v int) {
+	q.r = append(q.r, v)
+}
+
+func (q *Deque) PopFront() (v int) {
+	if len(q.l) > 0 {
+		q.l, v = q.l[:len(q.l)-1], q.l[len(q.l)-1]
+	} else {
+		v, q.r = q.r[0], q.r[1:]
+	}
+	return
+}
+
+func (q *Deque) PopBack() (v int) {
+	if len(q.r) > 0 {
+		q.r, v = q.r[:len(q.r)-1], q.r[len(q.r)-1]
+	} else {
+		v, q.l = q.l[0], q.l[1:]
+	}
+	return
+}
+
+func (q Deque) Front() int {
+	if len(q.l) > 0 {
+		return q.l[len(q.l)-1]
+	}
+	return q.r[0]
+}
+
+func (q Deque) Back() int {
+	if len(q.r) > 0 {
+		return q.r[len(q.r)-1]
+	}
+	return q.l[0]
+}
+
+func (q Deque) Get(i int) int {
+	if i < len(q.l) {
+		return q.l[len(q.l)-1-i]
+	}
+	return q.r[i-len(q.l)]
+}
diff --git a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.java b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.java
index 157a330d7b6ad..7b688798322d8 100644
--- a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.java	
+++ b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.java	
@@ -2,24 +2,22 @@ class Solution {
     public int maximumRobots(int[] chargeTimes, int[] runningCosts, long budget) {
         Deque q = new ArrayDeque<>();
         int n = chargeTimes.length;
-        long s = 0;
-        int j = 0;
         int ans = 0;
-        for (int i = 0; i < n; ++i) {
-            int a = chargeTimes[i], b = runningCosts[i];
-            while (!q.isEmpty() && chargeTimes[q.getLast()] <= a) {
+        long s = 0;
+        for (int l = 0, r = 0; r < n; ++r) {
+            s += runningCosts[r];
+            while (!q.isEmpty() && chargeTimes[q.peekLast()] <= chargeTimes[r]) {
                 q.pollLast();
             }
-            q.offer(i);
-            s += b;
-            while (!q.isEmpty() && chargeTimes[q.getFirst()] + (i - j + 1) * s > budget) {
-                if (q.getFirst() == j) {
+            q.offerLast(r);
+            while (!q.isEmpty() && (r - l + 1) * s + chargeTimes[q.peekFirst()] > budget) {
+                if (q.peekFirst() == l) {
                     q.pollFirst();
                 }
-                s -= runningCosts[j++];
+                s -= runningCosts[l++];
             }
-            ans = Math.max(ans, i - j + 1);
+            ans = Math.max(ans, r - l + 1);
         }
         return ans;
     }
-}
\ No newline at end of file
+}
diff --git a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.py b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.py
index 122f1522c478d..09f3232119c0b 100644
--- a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.py	
+++ b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.py	
@@ -3,16 +3,16 @@ def maximumRobots(
         self, chargeTimes: List[int], runningCosts: List[int], budget: int
     ) -> int:
         q = deque()
-        ans = j = s = 0
-        for i, (a, b) in enumerate(zip(chargeTimes, runningCosts)):
-            while q and chargeTimes[q[-1]] <= a:
+        ans = s = l = 0
+        for r, (t, c) in enumerate(zip(chargeTimes, runningCosts)):
+            s += c
+            while q and chargeTimes[q[-1]] <= t:
                 q.pop()
-            q.append(i)
-            s += b
-            while q and chargeTimes[q[0]] + (i - j + 1) * s > budget:
-                if q[0] == j:
+            q.append(r)
+            while q and (r - l + 1) * s + chargeTimes[q[0]] > budget:
+                if q[0] == l:
                     q.popleft()
-                s -= runningCosts[j]
-                j += 1
-            ans = max(ans, i - j + 1)
+                s -= runningCosts[l]
+                l += 1
+            ans = max(ans, r - l + 1)
         return ans
diff --git a/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.ts b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.ts
new file mode 100644
index 0000000000000..22283dbfd3f9c
--- /dev/null
+++ b/solution/2300-2399/2398.Maximum Number of Robots Within Budget/Solution.ts	
@@ -0,0 +1,116 @@
+function maximumRobots(chargeTimes: number[], runningCosts: number[], budget: number): number {
+    const q = new Deque();
+    const n = chargeTimes.length;
+    let [ans, s] = [0, 0];
+    for (let l = 0, r = 0; r < n; ++r) {
+        s += runningCosts[r];
+        while (!q.isEmpty() && chargeTimes[q.backValue()!] <= chargeTimes[r]) {
+            q.popBack();
+        }
+        q.pushBack(r);
+        while (!q.isEmpty() && (r - l + 1) * s + chargeTimes[q.frontValue()!] > budget) {
+            if (q.frontValue() === l) {
+                q.popFront();
+            }
+            s -= runningCosts[l++];
+        }
+        ans = Math.max(ans, r - l + 1);
+    }
+    return ans;
+}
+
+class Node {
+    value: T;
+    next: Node | null;
+    prev: Node | null;
+
+    constructor(value: T) {
+        this.value = value;
+        this.next = null;
+        this.prev = null;
+    }
+}
+
+class Deque {
+    private front: Node | null;
+    private back: Node | null;
+    private size: number;
+
+    constructor() {
+        this.front = null;
+        this.back = null;
+        this.size = 0;
+    }
+
+    pushFront(val: T): void {
+        const newNode = new Node(val);
+        if (this.isEmpty()) {
+            this.front = newNode;
+            this.back = newNode;
+        } else {
+            newNode.next = this.front;
+            this.front!.prev = newNode;
+            this.front = newNode;
+        }
+        this.size++;
+    }
+
+    pushBack(val: T): void {
+        const newNode = new Node(val);
+        if (this.isEmpty()) {
+            this.front = newNode;
+            this.back = newNode;
+        } else {
+            newNode.prev = this.back;
+            this.back!.next = newNode;
+            this.back = newNode;
+        }
+        this.size++;
+    }
+
+    popFront(): T | undefined {
+        if (this.isEmpty()) {
+            return undefined;
+        }
+        const value = this.front!.value;
+        this.front = this.front!.next;
+        if (this.front !== null) {
+            this.front.prev = null;
+        } else {
+            this.back = null;
+        }
+        this.size--;
+        return value;
+    }
+
+    popBack(): T | undefined {
+        if (this.isEmpty()) {
+            return undefined;
+        }
+        const value = this.back!.value;
+        this.back = this.back!.prev;
+        if (this.back !== null) {
+            this.back.next = null;
+        } else {
+            this.front = null;
+        }
+        this.size--;
+        return value;
+    }
+
+    frontValue(): T | undefined {
+        return this.front?.value;
+    }
+
+    backValue(): T | undefined {
+        return this.back?.value;
+    }
+
+    getSize(): number {
+        return this.size;
+    }
+
+    isEmpty(): boolean {
+        return this.size === 0;
+    }
+}