题目:

有一个 单线程 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 的函数的独占时间。

示例 1:

输入: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 个单位时间。
示例 2:

输入: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 个单位时间。
示例 3:

输入:n = 2, logs = ["0:start:0","0:start:2","0:end:5","1:start:6","1:end:6","0:end:7"]
输出:[7,1]
解释:
函数 0 在时间戳 0 的起始开始执行,执行 2 个单位时间,并递归调用它自身。
函数 0(递归调用)在时间戳 2 的起始开始执行,执行 4 个单位时间。
函数 0(初始调用)恢复执行,并立刻调用函数 1 。
函数 1在时间戳 6 的起始开始执行,执行 1 个单位时间,于时间戳 6 的末尾结束执行。
函数 0(初始调用)在时间戳 7 的起始恢复执行,执行 1 个单位时间,于时间戳 7 的末尾结束执行。
所以函数 0 总共执行 2 + 4 + 1 = 7 个单位时间,函数 1 总共执行 1 个单位时间。
示例 4:

输入:n = 2, logs = ["0:start:0","0:start:2","0:end:5","1:start:7","1:end:7","0:end:8"]
输出:[8,1]
示例 5:

输入:n = 1, logs = ["0:start:0","0:end:0"]
输出:[1]

提示:

  • 1 <= n <= 100
  • 1 <= logs.length <= 500
  • 0 <= function_id < n
  • 0 <= timestamp <= 109
  • 两个开始事件不会在同一时间戳发生
  • 两个结束事件不会在同一时间戳发生
  • 每道函数都有一个对应 "start" 日志的 "end" 日志

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

解题思路:

利用栈来模拟实现过程:

将logs中的每一个字符串,以冒号作为分隔符分成三小段,第一段为函数序号funId,第二段为函数名称type,第三段为所走的步长timestep。利用栈来存放函数的序号,从前往后遍历每一个字符串,根据遇到的函数名分情况讨论:

  • 如果当前函数名为start:从当前函数的开始时间timestep到上一次start函数的当前时间cur都为上一函数的执行时间即 timestep - cur ,在栈不为空的情况下,将计算出的时间累加到栈顶函数上,然后将当前函数序号入栈,更新当前时间;
  • 如果当前函数名为end:当前函数的结束时间到上一次记录函数的当前时长即timestep - cur + 1,为该函数的执行时间,将其累加到当前函数中,更新当前时间 cur = timstep + 1;

模拟示例4的过程:

代码:

 1 class Solution {
2 public int[] exclusiveTime(int n, List<String> logs) {
3 //用栈来记录函数的序号
4 Deque<Integer> stack = new ArrayDeque<>();
5 //定义数组来存放结果
6 int[] res = new int[n];
7 //当前时间为0
8 int cur = 0;
9 for(String log : logs){
10 String[] ss = log.split(":");
11 int funId = Integer.parseInt(ss[0]);
12 String type = ss[1];
13 int timeStep = Integer.parseInt(ss[2]);
14 if(type.equals("start")){
15 if(!stack.isEmpty()){
16 //为start时,发起时间到上一次记录的当前时间差均为执行时间
17 res[stack.peekLast()] += timeStep - cur;
18 }
19 stack.addLast(funId);
20 cur = timeStep;
21 }else{
22 //为end时,结束时间与上一次当前时间的时长就是执行时间
23 res[stack.pollLast()] += timeStep - cur + 1;
24 //更新当前时间
25 cur = timeStep + 1;
26 }
27 }
28 return res;
29 }
30 }

力扣636(java)-函数的独占时间(中等)的更多相关文章

  1. Java实现 LeetCode 636 函数的独占时间(栈)

    636. 函数的独占时间 给出一个非抢占单线程CPU的 n 个函数运行日志,找到函数的独占时间. 每个函数都有一个唯一的 Id,从 0 到 n-1,函数可能会递归调用或者被其他函数调用. 日志是具有以 ...

  2. Leetcode 636.函数的独占时间

    函数的独占时间 给出一个非抢占单线程CPU的 n 个函数运行日志,找到函数的独占时间. 每个函数都有一个唯一的 Id,从 0 到 n-1,函数可能会递归调用或者被其他函数调用. 日志是具有以下格式的字 ...

  3. [Swift]LeetCode636. 函数的独占时间 | Exclusive Time of Functions

    Given the running logs of n functions that are executed in a nonpreemptive single threaded CPU, find ...

  4. 力扣算法经典第一题——两数之和(Java两种方式实现)

    一.题目 难度:简单 给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数, 并返回它们的数组下标. 你可以假设每种输入只会对应一 ...

  5. 【Warrior刷题笔记】力扣169. 多数元素 【排序 || 哈希 || 随机算法 || 摩尔投票法】详细注释 不断优化 极致压榨

    题目 来源:力扣(LeetCode) 链接:https://leetcode-cn.com/problems/majority-element/ 注意,该题在LC中被标注为easy,所以我们更多应该关 ...

  6. JS调用Java函数--DWR框架

    (1)dwr与ssh框架整合教程dwr框架介绍. DWR(Direct Web Remoting)是一个用于改善web页面与Java类交互的远程服务器端Ajax开源框架,可以帮助开发人员开发包含AJA ...

  7. 力扣算法题—069x的平方根

    实现 int sqrt(int x) 函数. 计算并返回 x 的平方根,其中 x 是非负整数. 由于返回类型是整数,结果只保留整数的部分,小数部分将被舍去. 示例 1: 输入: 4 输出: 2 示例 ...

  8. [原创]Java项目统一UTC时间方案

    Java项目统一UTC时间方案 作者:Gods_巨蚁 引言 近期团队的个别项目在进行框架升级后,部分时间值存在8小时误差,原因是错误的将数据库中的时间数据理解成了UTC时间(旧版本认为是北京时间) 考 ...

  9. java 获取当前系统时间

    Java的Date获取时间函数都是deprecated 可以使用: https://stackoverflow.com/questions/5175728/how-to-get-the-current ...

  10. java中自带时间类使用方法实例 Date,Timestamp,DateFormat

    我们将以Java自带的时间日期类和当中的处理函数进行分析. 一.与时间日期有关的类. java.util.Date. 实现类,其对象具有时间.日期组件. java.util.Calendar. 抽象类 ...

随机推荐

  1. Proxmark3入门指南

    Proxmark3笔记 --Proxmark3完全入门指南 写在前面 这里所有针对扇区.区块的计数都是从0开始算 一些需要知道的知识 为了能看懂笔记,需要能回答以下问题 ID卡和IC卡主要的区别是什么 ...

  2. 一些网络编程方面的总结,以及redis、memcache、nginx组件的一些介绍

    网络编程主要关注的一些问题 主要关注3个方面的问题 连接的建立 连接的断开 消息的发送和到达 连接的建立 主要分为两种情况:服务器处理接受客户端的连接:服务端作为客户端的连接第三方服务: //这是服务 ...

  3. Android视音频基础知识

    学术概念 采样和采样频率: ⼀秒钟内采样的次数称为采样频率.采样频率越⾼,越接近原始信号,但是也加⼤了运算处理的复杂度.根据Nyquist采样定理,要想重建原始信号,采样频率必须⼤于信号中最⾼频率的两 ...

  4. MySQL(视图、事务、存储过程、函数、流程控制、索引)

    一 视图(了解) 什么是视图 视图就是通过查询得到一张虚拟表,然后保存下来,下次可以直接使用 为什么要用视图 如果要频繁的操作一张虚拟表(拼表组成的),你就可以制作成视图,后续直接操作 视图其实也是一 ...

  5. 记录--通过手写,分析Promise核心原理

    这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助 1. 定义整体结构 先写出构造函数,将Promise向外暴露 /* 自定义Promise函数模块:IIFE */ (function (w ...

  6. Android Graphics 多屏同显/异显

    " 亏功一篑,未成丘山.凿井九阶,不次水泽.行百里者半九十,小狐汔济濡其尾.故曰时乎,时不再来.终终始始,是谓君子." 01 前言 随着Android智能驾舱系统的普及各种信息交互 ...

  7. Java12版本特性【一文了解】

    「MoreThanJava」 宣扬的是 「学习,不止 CODE」,本系列 Java 基础教程是自己在结合各方面的知识之后,对 Java 基础的一个总回顾,旨在 「帮助新朋友快速高质量的学习」. 当然 ...

  8. 详解SSL证书系列(6)了解HTTP及网络基础

    使用HTTP协议访问Web 你知道当我们在网页浏览器(比如Chrome)的地址栏中输入URL时,Web网页是如何呈现的吗?   Web页面当然不会凭空显示出来.根据Web浏览器地址栏中指定的URL,W ...

  9. VIVADO原理图中的概念

    VIVADO原理图的基本作用 * 查看不同层次下的逻辑关系或者网表关系 * 检查逻辑设计是否可以通过数字电路实现 * 观察重要的信号的走向,分析可能的优化方向 VIVADO原理图几个基本概念 (1) ...

  10. KingbaseES 垃圾回收原理以及如何预防膨胀更新

    背景 KingbaseESV8R6支持snapshot too old 那么实际工作中,经常看到表又膨胀了,那么我们讨论一下导致对象膨胀的常见原因有哪些呢? 未开启autovacuum,对于未开启au ...