返回

函数嵌套的调用,如何计算独占时间?

后端

解题思路

这道题的核心在于如何追踪函数的执行历史,并从中提取出独占时间。我们可以使用栈来实现这个功能。当一个函数开始执行时,我们将它的信息压入栈中。当它执行结束时,我们将它的信息从栈中弹出。这样一来,栈中的函数就总是当前正在执行的函数。我们可以通过栈来追踪函数的调用关系,并计算出每个函数的独占时间。

具体步骤如下:

  1. 初始化一个栈,并将其命名为callStack
  2. 遍历函数执行历史记录,并依次处理每条记录。
  3. 如果当前记录表示一个函数的开始,我们将该函数的信息压入栈中。
  4. 如果当前记录表示一个函数的结束,我们将该函数的信息从栈中弹出,并计算出它的独占时间。
  5. 如果当前记录表示一个函数的中间调用,我们将该函数的信息压入栈中,并将栈顶函数的独占时间减去当前函数的执行时间。
  6. 重复步骤 2 到步骤 5,直到处理完所有函数执行历史记录。

代码实现

def exclusive_time(n, logs):
    """
    :type n: int
    :type logs: List[str]
    :rtype: List[int]
    """
    # 初始化栈
    callStack = []
    # 初始化结果列表
    result = [0] * n

    # 遍历函数执行历史记录
    for log in logs:
        # 分割日志
        function_id, event, time = log.split(':')
        function_id = int(function_id)
        time = int(time)

        # 如果是函数开始事件
        if event == 'start':
            # 将函数信息压入栈中
            callStack.append((function_id, time))
        # 如果是函数结束事件
        else:
            # 将函数信息从栈中弹出
            function_id, start_time = callStack.pop()
            # 计算独占时间
            result[function_id] += time - start_time + 1
            # 如果栈不为空,更新栈顶函数的独占时间
            if callStack:
                result[callStack[-1][0]] -= time - start_time

    return result


if __name__ == '__main__':
    n = 2
    logs = ["0:start:0", "1:start:2", "1:end:5", "0:end:6"]
    print(exclusive_time(n, logs))  # [3, 4]

时间复杂度

本算法的时间复杂度为O(n),其中n是函数执行历史记录的长度。

空间复杂度

本算法的空间复杂度为O(n),其中n是函数执行历史记录的长度。