The goal is to calculate how much exclusive time each function spends running — i.e., excluding the time consumed by any function it called.
Since the execution happens on a single-threaded CPU, we can simulate the behavior using a stack:
When a function starts, we pause the currently running function (if any).
When a function ends, we pop it off the stack and add its time.
If a function resumes after a nested call, we update its start timestamp accordingly.
Complexity
Space Complexity
Time Complexity
Code
public int[] exclusiveTime(int totalFunctions, List<String> logs) {
int[] exclusiveTimes = new int[totalFunctions];
// Stack to store currently running function info: [functionId, startTime]
Stack<int[]> callStack = new Stack<>();
for (String logEntry : logs) {
String[] parts = logEntry.split(":");
int functionId = Integer.parseInt(parts[0]);
String action = parts[1];
int timestamp = Integer.parseInt(parts[2]);
if (action.equals("start")) {
// Pause the current running function, if any
if (!callStack.isEmpty()) {
int[] currentFunction = callStack.peek();
int duration = timestamp - currentFunction[1];
exclusiveTimes[currentFunction[0]] += duration;
}
// Start the new function
callStack.push(new int[]{functionId, timestamp});
} else { // action == "end"
// Function ends, calculate total time it ran (inclusive)
int[] finishedFunction = callStack.pop();
int duration = timestamp - finishedFunction[1] + 1;
exclusiveTimes[finishedFunction[0]] += duration;
// Resume the parent function (if any), updating its start time
if (!callStack.isEmpty()) {
int[] parentFunction = callStack.peek();
parentFunction[1] = timestamp + 1; // resumes right after current ends
}
}
}
return exclusiveTimes;
}