Talentd
FleetCode
Make and follow sheets.Sign in

Maximum Number of Robots Within Budget solution and explanation

HardArrayBinary SearchHeap (Priority Queue)Monotonic Queue8 min read39.4% acceptanceUpdated 9 Apr 2026
Leetcode 2398. Maximum Number of Robots Within Budget | Biweekly Contest 86. | Hard | Most OptimalCode with Alisha · 38:45 · 3K viewsWatch on YouTube
9 more videos on this problem
  1. Leetcode 2398. Maximum Number of Robots Within Budget | Biweekly Contest 86. | Hard | Most OptimalCode with Alisha · 38:45 · 3K views
  2. 2398. Maximum Number of Robots Within Budget | Biweekly Contest 86 | LeetCode 2398Bro Coders · 12:51 · 2K views
  3. Biweekly Contest 86 | 6143. Maximum Number of Robots Within BudgetcodingMohan · 23:00 · 1K views
  4. 2398. Maximum Number of Robots Within Budget | Leetcode Biweekly Contest 86 | BINARY SEARCHcode Explainer · 15:14 · 749 views
  5. Maximum Number of Robots Within Budget - Leetcode Biweekly Contest 86Gopala Krishna Reddy Maguluri · 0:29 · 715 views
  6. 2398. Maximum Number of Robots Within Budget (Leetcode Hard)Programming Live with Larry · 24:36 · 641 views
  7. 【每日一题】LeetCode 2398. Maximum Number of Robots Within BudgetHuifeng Guan · 23:15 · 438 views
  8. Leetcode 2398. Maximum Number of Robots Within BudgetAlgorithms Casts · 23:10 · 316 views
  9. Leetcode 2398. Maximum Number of Robots Within Budget (monotonic queue)LetsCode · 9:39 · 189 views
  10. Leetcode 2398-s2. Maximum Number of Robots Within Budget-two-pointer sliding window, monotonic stackCode-Yao · 13:32 · 157 views

The problem

You have n robots. You are given two 0-indexed integer arrays, chargeTimes and runningCosts, both of length n. The ith robot costs chargeTimes[i] units to charge and costs runningCosts[i] units to run. You are also given an integer budget.

The total cost of running k chosen robots is equal to max(chargeTimes) + k * sum(runningCosts), where max(chargeTimes) is the largest charge cost among the k robots and sum(runningCosts) is the sum of running costs among the k robots.

Return the maximum number of consecutive robots you can run such that the total cost does not exceed budget.

Example 1:

Input: chargeTimes = [3,6,1,3,4], runningCosts = [2,1,3,4,5], budget = 25
Output: 3
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.

Example 2:

Input: chargeTimes = [11,12,19], runningCosts = [10,8,7], budget = 19
Output: 0
Explanation: No robot can be run that does not exceed the budget, so we return 0.

Constraints:

  • chargeTimes.length == runningCosts.length == n
  • 1 <= n <= 5 * 104
  • 1 <= chargeTimes[i], runningCosts[i] <= 105
  • 1 <= budget <= 1015

Approach overview

Problem Overview: You are given two arrays representing robot chargeTimes and runningCosts. Running k robots costs max(chargeTimes in window) + k * sum(runningCosts in window). The task is to find the largest group of consecutive robots that can run without exceeding the given budget.

Approach 1: Sliding Window with Monotonic Deque (O(n) time, O(n) space)

This is the optimal solution and relies on a sliding window combined with a monotonic queue. Expand the right pointer to include more robots while maintaining the sum of runningCosts. A deque keeps indices of robots in decreasing order of chargeTimes, so the front always holds the maximum charge time in the current window. Each time the window grows, compute the cost using maxCharge + windowSize * runningCostSum. If the cost exceeds the budget, move the left pointer forward and update the structures. Every element enters and leaves the deque at most once, giving linear time complexity. This approach works well because it efficiently tracks the maximum value while dynamically adjusting the window.

Approach 2: Binary Search with Prefix Sum (O(n log n) time, O(n) space)

This approach searches for the maximum valid window size using binary search. For a candidate size k, check if any subarray of length k satisfies the budget constraint. A prefix sum array allows constant-time computation of the sum of runningCosts for any window. To evaluate the maximum chargeTimes within each window, maintain a deque that stores indices in decreasing order, similar to the sliding window maximum technique. If at least one window of size k meets the budget condition, increase the search range; otherwise decrease it. Binary search narrows down the largest feasible window length.

Recommended for interviews: Interviewers typically expect the sliding window + monotonic deque solution. It demonstrates strong understanding of window expansion, maintaining dynamic maximum values, and amortized O(n) processing. The binary search approach is also valid and easier to reason about for some candidates, but the linear-time sliding window solution shows deeper algorithmic skill.

Approach 1: Approach 1: Sliding Window with Deque for Maximum

This approach involves using a sliding window technique along with a deque to maintain the maximum charge time within the current window. The goal is to efficiently manage the constraints such as recalculating the maximum value without iterating over the entire window each time.

We slide a window (i.e., a contiguous subarray) over the robots. The window expands by including a new robot, and contracts when the budget constraint is violated. Within this window, the max function and the sum function are used to compute the total cost. The sliding window and deque help manage the max charge time efficiently by allowing for constant-time insertion and removal of the charge times.

from collections import deque

def max_robots(chargeTimes, runningCosts, budget):
    n = len(chargeTimes)
    left = 0
    total_running_cost = 0
    deq = deque()
    max_robots = 0
    
    for right in range(n):
        # Add the new element to the running cost
        total_running_cost += runningCosts[right]
        
        # Maintain the deque for maximum charge time
        while deq and chargeTimes[deq[-1]] <= chargeTimes[right]:
            deq.pop()
        deq.append(right)
        
        # Calculate the total cost for current window
        while deq and (chargeTimes[deq[0]] + (right - left + 1) * total_running_cost) > budget:
            if deq[0] == left:
                deq.popleft()
            total_running_cost -= runningCosts[left]
            left += 1
        
        # Update maximum number of robots
        max_robots = max(max_robots, right - left + 1)
    
    return max_robots

# Example usage
chargeTimes = [3, 6, 1, 3, 4]
runningCosts = [2, 1, 3, 4, 5]
budget = 25
print(max_robots(chargeTimes, runningCosts, budget)) # Output: 3
#include <iostream>
#include <vector>
#include <deque>
using namespace std;

int maxRobots(vector<int>& chargeTimes, vector<int>& runningCosts, long long budget) {
    int n = chargeTimes.size();
    deque<int> deq;
    int left = 0;
    long long total_running_cost = 0;
    int max_robots = 0;
    
    for (int right = 0; right < n; ++right) {
        total_running_cost += runningCosts[right];
        
        while (!deq.empty() && chargeTimes[deq.back()] <= chargeTimes[right]) {
            deq.pop_back();
        }
        deq.push_back(right);

        while (!deq.empty() && (chargeTimes[deq.front()] + (right - left + 1) * total_running_cost) > budget) {
            if (deq.front() == left) deq.pop_front();
            total_running_cost -= runningCosts[left];
            left++;
        }

        max_robots = max(max_robots, right - left + 1);
    }
    
    return max_robots;
}

int main() {
    vector<int> chargeTimes = {3, 6, 1, 3, 4};
    vector<int> runningCosts = {2, 1, 3, 4, 5};
    long long budget = 25;
    cout << maxRobots(chargeTimes, runningCosts, budget) << endl; // Output: 3
    return 0;
}

This Python function uses a deque to track the indices of chargeTimes for which we need to calculate the maximum effectively within a sliding window. The window's total running cost and the maximum charge time (determined by deque) are used to confirm whether the current set of robots fits within the given budget.

Complexity

The time complexity is O(n) because each element is processed at most twice by deque operations (once when added, once when removed). The space complexity is O(k) where k is the maximum number of elements that can fit in the deque, which is bounded by the number of robots.

Try this approach in the editor

Approach 2: Approach 2: Binary Search with Prefix Sum

This approach uses binary search to find the maximum size of subarrays where the cost does not exceed the budget. The idea is to use a combination of binary search and prefix sums to evaluate whether it's possible to run a specific number of robots simultaneously without exceeding the budget. For each midpoint in the binary search, you need to check possible windows using prefix sum calculations.

import java.util.*;

public class MaxRobots {
    public static int maxRobots(int[] chargeTimes, int[] runningCosts, long budget) {
        int n = chargeTimes.length;
        long[] runningCostPrefix = new long[n + 1];
        for (int i = 0; i < n; i++) {
            runningCostPrefix[i + 1] = runningCostPrefix[i] + runningCosts[i];
        }
        int left = 0, right = n, result = 0;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (canRunRobots(chargeTimes, runningCostPrefix, mid, budget)) {
                result = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return result;
    }

    private static boolean canRunRobots(int[] chargeTimes, long[] runningCostPrefix, int k, long budget) {
        Deque<Integer> deq = new ArrayDeque<>();
        for (int i = 0; i < chargeTimes.length; i++) {
            if (i >= k) {
                if (deq.peekFirst() == i - k) {
                    deq.pollFirst();
                }
            }
            while (!deq.isEmpty() && chargeTimes[deq.peekLast()] <= chargeTimes[i]) {
                deq.pollLast();
            }
            deq.addLast(i);
            if (i >= k - 1) {
                long totalCost = chargeTimes[deq.peekFirst()] + 
                                 k * (runningCostPrefix[i + 1] - runningCostPrefix[i + 1 - k]);
                if (totalCost <= budget) {
                    return true;
                }
            }
        }
        return false;
    }

    public static void main(String[] args) {
        int[] chargeTimes = {3, 6, 1, 3, 4};
        int[] runningCosts = {2, 1, 3, 4, 5};
        int budget = 25;
        System.out.println(maxRobots(chargeTimes, runningCosts, budget)); // Output: 3
    }
}
using System;
using System.Collections.Generic;

class MaxRobots {
    public static int MaxRobots(int[] chargeTimes, int[] runningCosts, long budget) {
        int n = chargeTimes.Length;
        long[] runningCostPrefix = new long[n + 1];
        for (int i = 0; i < n; i++) {
            runningCostPrefix[i + 1] = runningCostPrefix[i] + runningCosts[i];
        }

        int left = 0, right = n, result = 0;
        while (left <= right) {
            int mid = (left + right) / 2;
            if (CanRunRobots(chargeTimes, runningCostPrefix, mid, budget)) {
                result = mid;
                left = mid + 1;
            } else {
                right = mid - 1;
            }
        }
        return result;
    }

    private static bool CanRunRobots(int[] chargeTimes, long[] runningCostPrefix, int k, long budget) {
        LinkedList<int> deq = new LinkedList<int>();

        for (int i = 0; i < chargeTimes.Length; i++) {
            if (i >= k) {
                if (deq.First.Value == i - k) deq.RemoveFirst();
            }

            while (deq.Count > 0 && chargeTimes[deq.Last.Value] <= chargeTimes[i]) {
                deq.RemoveLast();
            }

            deq.AddLast(i);

            if (i >= k - 1) {
                long totalCost = chargeTimes[deq.First.Value] + k * (runningCostPrefix[i + 1] - runningCostPrefix[i + 1 - k]);
                if (totalCost <= budget) {
                    return true;
                }
            }
        }
        return false;
    }

    public static void Main() {
        int[] chargeTimes = { 3, 6, 1, 3, 4 };
        int[] runningCosts = { 2, 1, 3, 4, 5 };
        long budget = 25;
        Console.WriteLine(MaxRobots(chargeTimes, runningCosts, budget)); // Output: 3
    }
}

This Java solution applies a combination of binary search to find the maximum number of robots and uses deque within a helper function to manage the sliding window size of robots we are evaluating.

Complexity

The binary search part has a time complexity of O(log n), and for each mid calculation, the cost checks take O(n), leading to a total complexity of O(n log n). The space complexity is O(n) due to the use of the runningCostsPrefix array and deque.

Try this approach in the editor

Approach 3: Two Pointers + Monotonic Queue

The problem is essentially finding the maximum value within a sliding window, which can be solved using a monotonic queue.

We only need to use binary search to enumerate the size of the window k, and find the largest k that satisfies the problem requirements.

In the implementation process, we don't actually need to perform binary search enumeration. We just need to change the fixed window to a non-fixed window with double pointers.

The time complexity is O(n), and the space complexity is O(n), where n is the number of robots in the problem.

function maximumRobots(chargeTimes: number[], runningCosts: number[], budget: number): number {
    const q = new Deque<number>();
    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<T> {
    value: T;
    next: Node<T> | null;
    prev: Node<T> | null;

    constructor(value: T) {
        this.value = value;
        this.next = null;
        this.prev = null;
    }
}

class Deque<T> {
    private front: Node<T> | null;
    private back: Node<T> | 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;
    }
}
func maximumRobots(chargeTimes []int, runningCosts []int, budget int64) (ans int) {
	q := Deque{}
	s := int64(0)
	l := 0
	for r, t := range chargeTimes {
		s += int64(runningCosts[r])
		for !q.Empty() && chargeTimes[q.Back()] <= t {
			q.PopBack()
		}
		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[l])
			l++
		}
		ans = max(ans, r-l+1)
	}
	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)]
}
Try this approach in the editor

Complexity comparison

ApproachComplexity
Approach 1: Sliding Window with Deque for Maximum

The time complexity is O(n) because each element is processed at most twice by deque operations (once when added, once when removed). The space complexity is O(k) where k is the maximum number of elements that can fit in the deque, which is bounded by the number of robots.

Approach 2: Binary Search with Prefix Sum

The binary search part has a time complexity of O(log n), and for each mid calculation, the cost checks take O(n), leading to a total complexity of O(n log n). The space complexity is O(n) due to the use of the runningCostsPrefix array and deque.

Two Pointers + Monotonic Queue–

Complexity analysis

ApproachTimeSpaceWhen to Use
Sliding Window with Monotonic DequeO(n)O(n)Best overall solution. Efficient when scanning the array once while maintaining the maximum charge time.
Binary Search with Prefix SumO(n log n)O(n)Useful when reasoning about window size feasibility or when applying binary search on the answer.

Frequently asked questions

Is Maximum Number of Robots Within Budget easy or hard?

Maximum Number of Robots Within Budget is classified as a Hard problem on LeetCode. The difficulty comes from combining multiple techniques—sliding window, monotonic queue, and cost calculation—into one efficient O(n) solution.

Maximum Number of Robots Within Budget Python/Java solution

Python solutions typically use collections.deque to maintain the monotonic queue and a sliding window for O(n) processing. Java implementations often use ArrayDeque for the same purpose. Both versions maintain the maximum charge time and a running sum of costs to enforce the budget constraint.

How to solve Maximum Number of Robots Within Budget in O(n)?

Use a sliding window with two pointers and maintain the maximum charge time using a monotonic deque. Keep a running sum of runningCosts for the current window. Expand the window to the right, and when the total cost exceeds the budget, move the left pointer until the constraint is satisfied again.

What is the best approach for Maximum Number of Robots Within Budget?

The most efficient approach uses a sliding window with a monotonic deque. The deque maintains the maximum charge time inside the window while a running sum tracks running costs. This allows checking the cost formula in constant time while expanding and shrinking the window, giving an overall O(n) time complexity.

Is Maximum Number of Robots Within Budget asked at Google/Amazon/Meta?

Problems combining sliding window and monotonic queue patterns frequently appear in interviews at companies like Google, Amazon, and Meta. This problem specifically tests understanding of dynamic window constraints and maintaining maximum values efficiently.

What data structure is used in Maximum Number of Robots Within Budget?

The key data structure is a monotonic deque (monotonic queue) that stores indices of robots in decreasing order of chargeTimes. This allows constant-time access to the maximum charge time in the current window while supporting efficient insertions and removals during window adjustments.

What is the time complexity of Maximum Number of Robots Within Budget?

The optimal sliding window solution runs in O(n) time because each robot index is added and removed from the deque at most once. The binary search alternative runs in O(n log n) since it checks feasibility for different window sizes. Both approaches require O(n) additional space.

Comments

Now write it yourselfClose this page and solve Maximum Number of Robots Within Budget in the editor, without looking.
Practise Maximum Number of Robots Within Budget