zoukankan      html  css  js  c++  java
  • [Swift]LeetCode636. 函数的独占时间 | Exclusive Time of Functions

    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★
    ➤微信公众号:山青咏芝(shanqingyongzhi)
    ➤博客园地址:山青咏芝(https://www.cnblogs.com/strengthen/
    ➤GitHub地址:https://github.com/strengthen/LeetCode
    ➤原文地址: https://www.cnblogs.com/strengthen/p/10479079.html 
    ➤如果链接不是山青咏芝的博客园地址,则可能是爬取作者的文章。
    ➤原文已修改更新!强烈建议点击原文地址阅读!支持作者!支持原创!
    ★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★★

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

    Each function has a unique id, start from 0 to n-1. A function may be called recursively or by another function.

    A log is a string has this format : function_id:start_or_end:timestamp. For example, "0:start:0" means function 0 starts from the very beginning of time 0. "0:end:0" means function 0 ends to the very end of time 0.

    Exclusive time of a function is defined as the time spent within this function, the time spent by calling other functions should not be considered as this function's exclusive time. You should return the exclusive time of each function sorted by their function id.

    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 time 0, then it executes 2 units of time and reaches the end of time 1. 
    Now function 0 calls function 1, function 1 starts at time 2, executes 4 units of time and end at time 5.
    Function 0 is running again at time 6, and also end at the time 6, thus executes 1 unit of time. 
    So function 0 totally execute 2 + 1 = 3 units of time, and function 1 totally execute 4 units of time. 

    Note:

    1. Input logs will be sorted by timestamp, NOT log id.
    2. Your output should be sorted by function id, which means the 0th element of your output corresponds to the exclusive time of function 0.
    3. Two functions won't start or end at the same time.
    4. Functions could be called recursively, and will always end.
    5. 1 <= n <= 100

    给出一个非抢占单线程CPU的 n 个函数运行日志,找到函数的独占时间。

    每个函数都有一个唯一的 Id,从 0 到 n-1,函数可能会递归调用或者被其他函数调用。

    日志是具有以下格式的字符串:function_id:start_or_end:timestamp。例如:"0:start:0" 表示函数 0 从 0 时刻开始运行。"0:end:0" 表示函数 0 在 0 时刻结束。

    函数的独占时间定义是在该方法中花费的时间,调用其他函数花费的时间不算该函数的独占时间。你需要根据函数的 Id 有序地返回每个函数的独占时间。

    示例 1:

    输入:
    n = 2
    logs = 
    ["0:start:0",
     "1:start:2",
     "1:end:5",
     "0:end:6"]
    输出:[3, 4]
    说明:
    函数 0 在时刻 0 开始,在执行了  2个时间单位结束于时刻 1。
    现在函数 0 调用函数 1,函数 1 在时刻 2 开始,执行 4 个时间单位后结束于时刻 5。
    函数 0 再次在时刻 6 开始执行,并在时刻 6 结束运行,从而执行了 1 个时间单位。
    所以函数 0 总共的执行了 2 +1 =3 个时间单位,函数 1 总共执行了 4 个时间单位。
    

    说明:

    1. 输入的日志会根据时间戳排序,而不是根据日志Id排序。
    2. 你的输出会根据函数Id排序,也就意味着你的输出数组中序号为 0 的元素相当于函数 0 的执行时间。
    3. 两个函数不会在同时开始或结束。
    4. 函数允许被递归调用,直到运行结束。
    5. 1 <= n <= 100

    168ms

     1 class Solution {
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3         var ans = [Int](repeating: 0, count: n)
     4         
     5         var stack = [Int]()
     6         var lastEndTime = 0
     7         for log in logs {
     8             let components = log.split(separator: ":")
     9             let id = Int(components[0])!
    10             let isStart = components[1] == "start"
    11             let currentTime = Int(components[2])!
    12             
    13             if isStart {
    14                 if !stack.isEmpty {
    15                     ans[stack.last!] += currentTime - lastEndTime
    16                 }
    17                 stack.append(id)
    18                 lastEndTime = currentTime
    19                 continue
    20             } else {
    21                 // this is a end of some task
    22                 ans[stack.removeLast()] += currentTime - lastEndTime + 1
    23                 lastEndTime = currentTime + 1
    24             }            
    25         }
    26         return ans
    27     }
    28 }

    172ms

     1 class Solution {
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3         var exclusiveTotals = [Int](repeating: 0, count: n)
     4         var startedTasks = [(id: Int, startTime: Int)]()
     5 
     6         for (id, status, time) in parsedLogs(logs) {
     7             if status == "start" {
     8 
     9                 // update exclusive time of parent task before this (if any)
    10                 if let parentTask = startedTasks.last {
    11                     exclusiveTotals[parentTask.id] += time - parentTask.startTime
    12                 }
    13 
    14                 // push new task onto stack
    15                 startedTasks.append((id: id, startTime: time))
    16 
    17 
    18             } else if let previousTask = startedTasks.popLast() {
    19 
    20                 // update current ending task's exclusive time
    21                 exclusiveTotals[previousTask.id] += time - previousTask.startTime + 1
    22 
    23                 // update parent task's start time (if any)
    24                 if let parentTask = startedTasks.popLast() {
    25                     startedTasks.append((id: parentTask.id, startTime: time+1))
    26                 }
    27             }
    28         }
    29 
    30         return exclusiveTotals
    31     }
    32 
    33     private func parsedLogs(_ logs: [String]) -> [(Int, String, Int)] {
    34         return logs.map {
    35             let tokens = $0.split(separator: ":")
    36             return (Int(tokens[0])!, String(tokens[1]), Int(tokens[2])!)
    37         }
    38     }
    39 }

    180ms

     1 class Solution {    
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3         var result = Array(repeating: 0, count: n)
     4 
     5         let logRecords = logs.compactMap(parseLogString)
     6 
     7         guard logRecords.count > 1 else {
     8             return []
     9         }
    10 
    11         var lastRecord = logRecords[0]
    12         var stack = [LogRecord]()
    13         for logRecord in logRecords {
    14             let offset: Int = {
    15                 if lastRecord.type == .end && logRecord.type == .start {
    16                     return -1
    17                 } else if lastRecord.type == .start && logRecord.type == .end {
    18                     return 1
    19                 } else {
    20                     return 0
    21                 }
    22             }()
    23 
    24             let timeDiff = logRecord.time - lastRecord.time + offset
    25             if logRecord.type == .start {
    26                 // push on to the stack
    27                 if let topRecord = stack.last {
    28                     result[topRecord.id] += timeDiff
    29                 }
    30                 stack.append(logRecord)
    31             } else if logRecord.type == .end {
    32                 if let topRecord = stack.popLast() {
    33                     if topRecord.id != logRecord.id || topRecord.type != .start {
    34                         assertionFailure("input not correctly formatted")
    35                         return []
    36                     }
    37 
    38                     result[topRecord.id] += timeDiff
    39                 } else {
    40                     assertionFailure("input not correctly formatted")
    41                     return []
    42                 }
    43             }
    44 
    45             lastRecord = logRecord
    46         }
    47 
    48         return result
    49     }
    50 
    51     enum LogType: String {
    52         case start = "start"
    53         case end = "end"
    54     }
    55 
    56     struct LogRecord {
    57         var id: Int
    58         var type: LogType
    59         var time: Int
    60         init(id: Int, type: LogType, time: Int) {
    61             self.id = id
    62             self.type = type
    63             self.time = time
    64         }
    65     }
    66 
    67     func parseLogString(_ logString: String) -> LogRecord? {
    68         guard !logString.isEmpty else {
    69             return nil
    70         }
    71 
    72         let components = logString.split(separator: ":")
    73         guard components.count == 3 else {
    74             return nil
    75         }
    76 
    77         guard let id = Int(String(components[0])) else {
    78             return nil
    79         }
    80 
    81         guard let type = LogType(rawValue: String(components[1])) else {
    82             return nil
    83         }
    84 
    85         guard let time = Int(String(components[2])) else {
    86             return nil
    87         }
    88 
    89         return LogRecord(id: id, type: type, time: time)
    90     }    
    91 }

    188ms

     1 class Solution {
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3         var stack = [Int]()
     4         var res = Array(repeating: 0, count: n)
     5         var s = logs[0].split(separator: ":")
     6         stack.append(Int(s[0])!)
     7         var i = 1
     8         var prev = Int(s[2])
     9         while i < logs.count {
    10             s = logs[i].split(separator: ":")
    11             if s[1] == "start" {
    12                 if !stack.isEmpty {
    13                     let index = stack.last!
    14                     let val = res[index]
    15                     res[index] = val + Int(s[2])! - prev!
    16                 }
    17                 stack.append(Int(s[0])!)
    18                 prev = Int(s[2])
    19             } else {
    20                 let index = stack.last!
    21                 res[index] = res[index] + Int(s[2])! - prev! + 1
    22                 stack.removeLast()
    23                 prev = Int(s[2])! + 1
    24             }
    25             i += 1
    26         }
    27         return res
    28     }
    29 }

    Runtime: 208 ms
    Memory Usage: 20 MB
     1 class Solution {
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3         var stack = [Int]()
     4         var pre = 0
     5         var res = Array(repeating: 0, count: n)
     6         
     7         for log in logs {
     8             
     9             let tokens = log.components(separatedBy: ":")
    10             
    11             let id = Int(tokens[0])!
    12             let act = tokens[1]
    13             let time = Int(tokens[2])!
    14             
    15             if act == "start" {
    16                 
    17                 if !stack.isEmpty {
    18                     
    19                     let top = stack[stack.count - 1]
    20                     res[top] += time - pre
    21                 }
    22                 
    23                 stack.append(id)
    24                 pre = time
    25                 
    26             } else {
    27                 
    28                 res[stack.removeLast()] += time - pre + 1
    29                 pre = time + 1
    30             }
    31         }        
    32         return res
    33     }
    34 }

    232ms

     1 class Solution {
     2 func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3     var result = Array(repeating: 0, count: n)
     4     
     5     var funcStack = [Int]()
     6     var prev = 0
     7     
     8     for s in logs {
     9         let fId = Int(s.prefix(upTo: s.firstIndex(of: ":")!))!
    10         let time = Int(s.suffix(from: s.index(after: s.lastIndex(of: ":")!)))!
    11         
    12         if s.contains("start") {
    13             if let last = funcStack.last {
    14                 result[last] += time - prev
    15             }
    16             
    17             prev = time
    18             funcStack.append(fId)
    19         } else {
    20             if let last = funcStack.last {
    21                 result[last] += time - prev + 1
    22                 funcStack.removeLast()
    23                 prev = time + 1
    24             }
    25         }
    26     }
    27     return result
    28    }
    29 }

    248ms

     1 class Solution {
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3         var stack: [Int] = [] // store the function id
     4         var res: [Int] = Array(repeating: 0, count: n)
     5         var pre: Int = 0
     6         for log in logs {
     7             let l = log.components(separatedBy: ":")
     8             let id = Int(l[0])!
     9             let curr = Int(l[2])!
    10             if l[1] == "start" {
    11                 if !stack.isEmpty {
    12                     res[stack.last!] += curr - pre
    13                 }
    14                 stack.append(id)
    15                 pre = curr
    16             } else {
    17                 res[stack.last!] += (curr - pre + 1)
    18                 stack.removeLast()
    19                 pre = curr + 1
    20             }
    21         }        
    22         return res
    23     }
    24 }

    252ms

     1 class Solution {
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3 
     4         if n == 0 || logs.count == 0 { return [] }
     5         var tuples = [(Int, Bool, Int)]()
     6         logs.forEach {
     7             let vals = $0.components(separatedBy: ":")
     8             let id = Int(vals[0])!
     9             let isStart = vals[1] == "start"
    10             let time = Int(vals[2])!
    11             tuples.append((id, isStart, time))
    12         }
    13         
    14         var result = [Int](repeating: 0, count: n)
    15         var stack = [(Int, Bool, Int)]()
    16         var lastTime = 0
    17         
    18         tuples.forEach {
    19             if $0.1 {
    20                 if !stack.isEmpty {
    21                     let last = stack.last!
    22                     let time = $0.2 - lastTime
    23                     result[last.0] += time
    24                 }
    25                 lastTime = $0.2
    26                 stack.append($0)
    27             } else {
    28                 let last = stack.removeLast()
    29                 let time = $0.2 - lastTime + 1
    30                 result[last.0] += time
    31                 lastTime = $0.2 + 1
    32             }
    33         }        
    34         return result
    35     }
    36 }

    256ms

     1 class Solution {
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3         guard n != 0 && logs.count > 0 else {return []}
     4         var times = [Int](repeating: 0, count: n)
     5         
     6         var st = [(op: Int, runtime: Int)]()
     7         for log in logs {
     8             let comp = log.components(separatedBy: ":")
     9             guard comp.count == 3 else {continue}
    10             guard let op = Int(comp[0]), let currTime = Int(comp[2]) else {continue}
    11             
    12             
    13             if comp[1] == "start" {
    14                 if st.count > 0 {
    15                     let currTop = st.last!
    16                     times[currTop.op] += currTime - st[st.count - 1].runtime
    17                 }
    18                 st.append((op, currTime))
    19             } else {
    20                 if st.count == 0 || st.last!.op != op {return []}
    21                 let currTop = st.removeLast()
    22                 times[currTop.op] += currTime - currTop.runtime + 1
    23                 if st.count > 0 {
    24                     st[st.count - 1].runtime = currTime + 1
    25                 }
    26             }            
    27         }
    28         return times
    29     }
    30 }

    276ms

     1 class Solution {
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3         var stack = [(Int, Int)]()
     4         var ans = [Int](repeating: 0, count: n)
     5         for i in 0..<logs.count {
     6             let components = logs[i].components(separatedBy: ":")
     7             let timestamp = Int(components[2])!
     8             let functionID = Int(components[0])!
     9             let functionState = components[1]
    10             
    11             if functionState == "start" {
    12                 if let last = stack.last { // Count the last run
    13                     ans[last.0] += (timestamp - last.1) // timestamp is not inclusive
    14                 }
    15                 stack.append((functionID, timestamp))
    16             } else {
    17                 let last = stack.removeLast()
    18                 ans[functionID] += (timestamp - last.1 + 1) // timestamp is inclusive
    19                 if let last = stack.last { // Update the last timestamp
    20                     stack.removeLast()
    21                     stack.append((last.0, timestamp + 1))
    22                 }
    23             }
    24         }
    25         return ans
    26     }
    27 }

    284ms

     1 class Solution {    
     2     func parseString(_ log: String) -> (Int, Int, Bool) {
     3         let start = ":start:"
     4         let end = ":end:"
     5         var separator = ""
     6         if log.contains(start) {
     7             let nums = log.components(separatedBy: start).compactMap { Int($0) }
     8             return (nums[0], nums[1], true)
     9         } else {
    10             let nums = log.components(separatedBy: end).compactMap { Int($0) }
    11             return (nums[0], nums[1], false)
    12         }
    13     }
    14     
    15     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
    16         var stack = [Int]()
    17         var exclusiveTime = Array(repeating: 0, count: n)
    18         var lastTimestamp = 0
    19         for log in logs {
    20             let (id, time, isStart) = parseString(log)
    21             if let lastId = stack.last {
    22                 exclusiveTime[lastId] += time - lastTimestamp
    23                 if !isStart {
    24                     exclusiveTime[lastId] += 1
    25                 }
    26             }
    27             lastTimestamp = time
    28             if isStart {
    29                 stack.append(id)
    30             } else {
    31                 stack.removeLast()
    32                 lastTimestamp += 1
    33             }
    34         }
    35         return exclusiveTime
    36     }
    37 }

    296ms

     1 class Solution {
     2     func exclusiveTime(_ n: Int, _ logs: [String]) -> [Int] {
     3         var res = Array(repeating: 0, count: n)
     4         var currRunning: Int?
     5         var currStart: Int=0
     6         var callStack = [Int]()
     7         for log in logs {
     8             let component = log.components(separatedBy: ":")
     9             let funcID = Int(component[0])!
    10             let funcTime = Int(component[2])!
    11             let isStart = (component[1] == "start")
    12             if isStart {
    13                 
    14                 if currRunning != nil {
    15                     res[currRunning!]+=funcTime-currStart
    16                 }
    17                     currRunning = funcID
    18                     currStart = funcTime
    19                     callStack.append(funcID)
    20                 //} else {
    21                     //recursive, dont need to update
    22                 //}
    23                 
    24                 
    25             } else { //end
    26                 guard funcID == callStack.last! else { return [] }
    27                 if let currRunning = currRunning {
    28                     res[currRunning]+=funcTime-currStart+1
    29                 }
    30                 callStack = Array(callStack.dropLast())
    31                 currRunning = callStack.last
    32                 currStart = funcTime+1
    33             }
    34         }
    35         return res
    36     }
    37 }
  • 相关阅读:
    37个绝对不容错过的HTML5教程和资源
    Google的自动驾驶汽车无事故成功完成30万英里的驾驶路程
    一个基于jQuery Mobile的移动设备实时幻灯javascript类库 taciónJS
    推荐免费黑色UI工具包下载
    分享一些前端开发人员必备的工具,脚本和资源
    使用HTML5画布实现的超棒javascript动画仪表板:gauge.js
    Google(谷歌)将打算在搜索结果中展示Gmail内容
    免费资源下载:30个用户界面工具栏图标设计
    一张超诡异的HTML图片“松鼠” 是图片同时也是web页面
    带给你设计灵感的30个超棒的暗色系网站设计
  • 原文地址:https://www.cnblogs.com/strengthen/p/10479079.html
Copyright © 2011-2022 走看看