返回
剖析LeetCode 636:揭秘函数的独占时间
前端
2023-10-23 06:23:23
程序员经常在 LeetCode 上磨炼他们的算法和数据结构技能。 LeetCode 636 是一个尤其引人入胜的问题,它考察了程序员对线程执行和函数独占时间的理解。
问题
有一个单线程 CPU 正在运行一个含有 n 道函数的程序。每道函数都有一个位于 [start, end) 范围内的独占时间,即在这段时间内,CPU 仅执行该函数。此外,每个函数可能调用其他函数,形成一个嵌套的调用关系。
给定 n 道函数的独占时间和调用关系,要求返回每个函数的独占时间。
剖析问题
解决此问题的第一步是了解线程执行、调用栈和堆栈等关键概念:
- 线程执行: CPU 执行程序时,会创建一个线程,该线程顺序执行程序中的指令。
- 调用栈: 当函数调用另一个函数时,被调用函数的信息会被压入调用栈。当被调用函数返回时,它的信息会被弹出调用栈。
- 堆栈: 堆栈是存储函数局部变量和参数的内存区域。
算法和数据结构
解决 LeetCode 636 的核心在于使用堆栈来模拟函数调用关系。具体步骤如下:
- 初始化: 创建一个堆栈和一个哈希表来存储函数的独占时间。
- 遍历日志: 按时间顺序遍历日志中的事件:
- 如果是一次函数调用事件,则将函数信息压入堆栈,并将函数的独占时间初始化为 0。
- 如果是一次函数返回事件,则从堆栈中弹出函数信息,并更新其独占时间。
- 计算独占时间: 对于堆栈中的每个函数,其独占时间等于其子函数的独占时间之和加上其自身独占时间。
- 返回结果: 返回哈希表中所有函数的独占时间。
代码示例
def exclusiveTime(n, logs):
stack = []
time = {}
for log in logs:
function, event, timestamp = log.split(':')
if event == 'start':
stack.append((int(function), int(timestamp)))
else:
start_function, start_time = stack.pop()
total_time = int(timestamp) - start_time + 1
time[start_function] = time.get(start_function, 0) + total_time
if stack:
time[stack[-1][0]] -= total_time
return [time[i] for i in range(n)]
结论
通过理解线程执行、调用栈和堆栈等基本概念,程序员可以有效地解决 LeetCode 636 等复杂算法问题。该问题不仅考验了对算法和数据结构的掌握,还培养了对编程执行过程的深刻理解。