给定一个日志列表 INLINECODEc559137c,其中 INLINECODE40f411f5 代表第 i 条日志消息,格式为字符串 INLINECODEc26f3ea5。例如,INLINECODEc46618e9 表示 ID 为 0 的函数调用在时间戳 3 的开始时启动,而 "1:end:2" 表示 ID 为 1 的函数调用在时间戳 2 的结束时结束。请注意,一个函数可以被多次调用,甚至可能是递归调用。
函数的独占时间是指该程序中所有函数调用的执行时间总和。例如,如果一个函数被调用了两次,一次执行了 2 个时间单位,另一次执行了 1 个时间单位,那么独占时间就是 2 + 1 = 3。
我们需要返回一个数组来表示每个函数的独占时间,其中第 i 个索引处的值代表 ID 为 i 的函数的独占时间。
示例:
> 输入: n = 2, logs[] = {"0:start:0", "1:start:2", "1:end:5", "0:end:6"}
> 输出: [3,4]
> 解释:
>
>
> – 函数 0 在时间 0 的开始时启动,执行了 2 个时间单位,直到时间 1 的结束。
> – 函数 1 在时间 2 的开始时启动,执行了 4 个时间单位,直到时间 5 的结束。
> – 函数 0 在时间 6 的开始时恢复执行,并执行了 1 个时间单位。
> – 因此,函数 0 的总执行时间为 2 + 1 = 3 个单位,函数 1 的总执行时间为 4 个单位。
>
> 输入: n = 1, logs[] = {"0:start:0", "0:start:2", "0:end:5", "0:start:6", "0:end:6", "0:end:7"}
> 输出: [8]
> 解释:
>
>
> – 函数 0 在时间 0 的开始时启动,执行了 2 个时间单位,然后递归调用了自身。
> – 函数 0(递归调用)在时间 2 的开始时启动,执行了 4 个时间单位。
> – 函数 0(初始调用)恢复执行,随后立即再次调用自身。
> – 函数 0(第二次递归调用)在时间 6 的开始时启动,执行了 1 个时间单位。
> – 函数 0(初始调用)在时间 7 的开始时恢复执行,执行了 1 个时间单位。
> – 因此,函数 0 的总执行时间为 2 + 4 + 1 + 1 = 8 个单位。
方法: 为了解决这个问题,我们可以遵循以下思路:
> 这个想法很简单,每当我们看到一个 start(开始)日志时,我们就把它压入栈中。当我们遇到一个 end(结束)日志时,我们可以确定栈顶元素的 ID 与当前日志的 ID 是相同的,因为在这个 start 和 end 之间的所有已完成的 start/end 对都已经被移除了。我们要做的就是将 INLINECODE0ef80fdb 加到 INLINECODE3f066990 中。
>
>
> 例如:
>
>
> […, {0:start:3}] 且 当前项 = {0:end:6},我们计算 6 – 3 + 1。
>
>
> 然而,如果在 ID 为 0 的函数的开始和结束之间有其他函数调用怎么办?我们可以通过在完成任何内部函数(由 end 标记)时,减去该内部函数的耗时来处理这种情况。
>
>
> […, {0:start:3}, {2:start:4}] 且 当前项 = {2:end:5},所以我们通过 INLINECODEb3388318 来增加 INLINECODE6dd916cb,然后从 INLINECODE108c2553 中减去 INLINECODE1a5defde,因为这 2 个时间单位被内部函数占用了。
>
>
> 所以,每当我们看到一个 end 日志时,我们必须确保将当前的 curr_length 从包含它的外部函数(如果存在)的时间中减去。
分步算法:
- 创建一个向量
****times****来存储每个函数的独占时间。 - 创建一个栈
****st****来存储日志条目。 - 遍历
****logs****数组: - 如果当前日志是
start(开始)条目: - 将该日志条目压入栈中。
- 如果当前日志是
end(结束)条目: - 从栈顶获取之前的
start(开始)日志条目。 - 计算 INLINECODE76bd87e9 和 INLINECODE1e8bc5f7 条目之间的时间差,并将其加到对应函数的
times向量中。 - 从栈中移除该
start日志条目。 - 如果栈不为空,从
times向量中减去前一个函数的时间差。 - 返回
times向量。
下面是该算法的实现:
C++
“cpp
#include
using namespace std;
// 用于存储日志信息的结构体
struct Log {
int id;
string status;
int timestamp;
};
// 计算n个函数独占时间的函数
vector exclusiveTime(int n, vector& logs)
{
// 初始化 times 向量,值为 0
vector times(n, 0);
// 创建一个栈来存储日志
stack st;
// 遍历日志
for (string log : logs) {
stringstream ss(log);
string temp, temp2, temp3;
getline(ss, temp, ‘:‘);
getline(ss, temp2, ‘:‘);
getline(ss, temp3, ‘:‘);
Log item = { stoi(temp), temp2, stoi(temp3) };
// 如果当前日志是 start 日志
if (item.status == "start") {
// 将日志压入栈中
st.push(item);
}
else { // 如果当前日志是 end 日志