• [LeetCode] 636. Exclusive Time of Functions


    On a single-threaded CPU, we execute a program containing n functions. Each function has a unique ID between 0 and n-1.

    Function calls are stored in a call stack: when a function call starts, its ID is pushed onto the stack, and when a function call ends, its ID is popped off the stack. The function whose ID is at the top of the stack is the current function being executed. Each time a function starts or ends, we write a log with the ID, whether it started or ended, and the timestamp.

    You are given a list logs, where logs[i] represents the ith log message formatted as a string "{function_id}:{"start" | "end"}:{timestamp}". For example, "0:start:3" means a function call with function ID 0 started at the beginning of timestamp 3, and "1:end:2" means a function call with function ID 1 ended at the end of timestamp 2. Note that a function can be called multiple times, possibly recursively.

    A function's exclusive time is the sum of execution times for all function calls in the program. For example, if a function is called twice, one call executing for 2 time units and another call executing for 1 time unit, the exclusive time is 2 + 1 = 3.

    Return the exclusive time of each function in an array, where the value at the ith index represents the exclusive time for the function with ID i.

    Example 1:

    Input: n = 2, logs = ["0:start:0","1:start:2","1:end:5","0:end:6"]
    Output: [3,4]
    Explanation:
    Function 0 starts at the beginning of time 0, then it executes 2 for units of time and reaches the end of time 1.
    Function 1 starts at the beginning of time 2, executes for 4 units of time, and ends at the end of time 5.
    Function 0 resumes execution at the beginning of time 6 and executes for 1 unit of time.
    So function 0 spends 2 + 1 = 3 units of total time executing, and function 1 spends 4 units of total time executing.
    

    Example 2:

    Input: n = 1, logs = ["0:start:0","0:start:2","0:end:5","0:start:6","0:end:6","0:end:7"]
    Output: [8]
    Explanation:
    Function 0 starts at the beginning of time 0, executes for 2 units of time, and recursively calls itself.
    Function 0 (recursive call) starts at the beginning of time 2 and executes for 4 units of time.
    Function 0 (initial call) resumes execution then immediately calls itself again.
    Function 0 (2nd recursive call) starts at the beginning of time 6 and executes for 1 unit of time.
    Function 0 (initial call) resumes execution at the beginning of time 7 and executes for 1 unit of time.
    So function 0 spends 2 + 4 + 1 + 1 = 8 units of total time executing.
    

    Example 3:

    Input: n = 2, logs = ["0:start:0","0:start:2","0:end:5","1:start:6","1:end:6","0:end:7"]
    Output: [7,1]
    Explanation:
    Function 0 starts at the beginning of time 0, executes for 2 units of time, and recursively calls itself.
    Function 0 (recursive call) starts at the beginning of time 2 and executes for 4 units of time.
    Function 0 (initial call) resumes execution then immediately calls function 1.
    Function 1 starts at the beginning of time 6, executes 1 unit of time, and ends at the end of time 6.
    Function 0 resumes execution at the beginning of time 6 and executes for 2 units of time.
    So function 0 spends 2 + 4 + 1 = 7 units of total time executing, and function 1 spends 1 unit of total time executing.

    Constraints:

    • 1 <= n <= 100
    • 1 <= logs.length <= 500
    • 0 <= function_id < n
    • 0 <= timestamp <= 109
    • No two start events will happen at the same timestamp.
    • No two end events will happen at the same timestamp.
    • Each function has an "end" log for each "start" log.

    函数的独占时间。

    有一个 单线程 CPU 正在运行一个含有 n 道函数的程序。每道函数都有一个位于  0 和 n-1 之间的唯一标识符。

    函数调用 存储在一个 调用栈 上 :当一个函数调用开始时,它的标识符将会推入栈中。而当一个函数调用结束时,它的标识符将会从栈中弹出。标识符位于栈顶的函数是 当前正在执行的函数 。每当一个函数开始或者结束时,将会记录一条日志,包括函数标识符、是开始还是结束、以及相应的时间戳。

    给你一个由日志组成的列表 logs ,其中 logs[i] 表示第 i 条日志消息,该消息是一个按 "{function_id}:{"start" | "end"}:{timestamp}" 进行格式化的字符串。例如,"0:start:3" 意味着标识符为 0 的函数调用在时间戳 3 的 起始开始执行 ;而 "1:end:2" 意味着标识符为 1 的函数调用在时间戳 2 的 末尾结束执行。注意,函数可以 调用多次,可能存在递归调用 。

    函数的 独占时间 定义是在这个函数在程序所有函数调用中执行时间的总和,调用其他函数花费的时间不算该函数的独占时间。例如,如果一个函数被调用两次,一次调用执行 2 单位时间,另一次调用执行 1 单位时间,那么该函数的 独占时间 为 2 + 1 = 3 。

    以数组形式返回每个函数的 独占时间 ,其中第 i 个下标对应的值表示标识符 i 的函数的独占时间。

    来源:力扣(LeetCode)
    链接:https://leetcode.cn/problems/exclusive-time-of-functions
    著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。

    题意不难理解,思路是stack,理由是无论这里面涉及多少函数的递归调用,一定是后开始跑的函数先结束,符合stack的后进先出的原则。我们用题目给的第一个例子跑一下。这里我们还需要一个变量 last 记录上一个函数进出 stack 的时间。

    • id = 每个函数的id
    • time = 每个log里表示的时间戳
    • operator = start/end

    对于任何函数是否入栈,触发的条件是看 log 里是否出现 start 或者 end,无论出现哪一个,都是需要结算的时候。如果遇到某个 log 是 start,说明是某个函数的开始时间,此时如果栈不为空,说明栈顶那个函数需要暂停一下了,我们需要把此时栈顶函数已经花掉的时间先入栈(time - last),然后再把当前函数的id入栈。

    如果遇到某个 log 是 end,就说明当前函数需要结算了,把栈顶元素弹出,此时这个函数的运行时间 = time - last + 1,并且要把 last 更新成 time + 1。

    时间O(n)

    空间O(n)

    Java实现

     1 class Solution {
     2     public int[] exclusiveTime(int n, List<String> logs) {
     3         int[] res = new int[n];
     4         Deque<Integer> stack = new ArrayDeque<>();
     5         int last = 0;
     6         for (String log : logs) {
     7             String[] strs = log.split("\\:");
     8             int id = Integer.parseInt(strs[0]);
     9             int time = Integer.parseInt(strs[2]);
    10             String operator = strs[1];
    11             if (operator.equals("start")) {
    12                 if (!stack.isEmpty()) {
    13                     res[stack.peek()] += time - last;
    14                 }
    15                 stack.push(id);
    16                 last = time;
    17             } else {
    18                 res[stack.pop()] += time - last + 1;
    19                 last = time + 1;
    20             }
    21         }
    22         return res;
    23     }
    24 }

    LeetCode 题目总结

  • 相关阅读:
    数据库事务的特性以及MySQL数据库的隔离级别
    IDEA开发工具如何实现热部署
    MongoDB 逻辑还原工具mongorestore
    MongoDB 逻辑备份工具mongodump
    MongoDB 4.X CRUD基本操作
    Linux Tools 之 iostat 工具总结
    MySQL Tools 之 mysql.server 脚本运用
    Oracle 11g R2 Sample Schemas 安装
    MongoDB 4.X 用户和角色权限管理总结
    Percona-Toolkit 之 pt-archiver 总结
  • 原文地址:https://www.cnblogs.com/cnoodle/p/16558451.html
Copyright © 2020-2023  润新知