What I do is that for every start, i push to the stack. But before pushing, I calculate the time it spent for the peek element.

For every end, i pop and compute time. And for the peek element, i update the start time as end time of it.

public int[] exclusiveTime(int n, List<String> logs) {
Stack<String[]> s = new Stack<>();
int[] result = new int[n];
for(int i = 0;i < logs.size(); i++) {
String[] log = logs.get(i).split(":");
if(log[1].equals("start")) {
if(!s.isEmpty()) {
String[] top = s.peek();
result[Integer.parseInt(top[0])] += Integer.parseInt(log[2]) - Integer.parseInt(top[2]) - 1;
}
s.push(new String[] {log[0], log[1], log[2]});
}else {
String[] top = s.pop();
result[Integer.parseInt(log[0])] += Integer.parseInt(log[2]) + 1 - Integer.parseInt(top[2]);
if(!s.isEmpty()) {
top = s.peek();
top[2] = log[2];
}
}
}
return result;
}

And you can also notice that log[1] "start" and "end" is not needed to be added to stack. But it could be needed if CPU is not single thread.