636. Exclusive Time of Functions

问题描述:

On a single threaded CPU, we execute some functions.  Each function has a unique id between 0 and N-1.

We store logs in timestamp order that describe when a function is entered or exited.

Each log is a string with this format: "{function_id}:{"start" | "end"}:{timestamp}".  For example, "0:start:3" means the function with id 0 started at the beginning of timestamp 3.  "1:end:2" means the function with id 1 ended at the end of timestamp 2.

A function's exclusive time is the number of units of time spent in this function.  Note that this does not include any recursive calls to child functions.

The CPU is single threaded which means that only one function is being executed at a given time unit.

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 the beginning of time 0, then it executes 2 units of time and reaches the end of time 1.
Now function 1 starts at the beginning of time 2, executes 4 units of time and ends at time 5.
Function 0 is running again at the beginning of time 6, and also ends at the end of time 6, thus executing 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.

Note:

  1. 1 <= n <= 100
  2. Two functions won't start or end at the same time.
  3. Functions will always log when they exit.

解题思路:

这道题要仔细读题,其实本质还是一个扫描线问题,但是有了一点小弯弯绕绕。

题目中说给出的log已经是时间顺序了,所以我们顺序访问每个log并结合以前信息就好啦。

这里要注意一个嵌套问题,就是在func0 运行过程中可以包含多个子程序如 func1, func2 若子程序之间存在空隙的话实则为func0在运行。

所以我们可以用一个栈来存储当前运行的程序。

start向栈内加入,end从栈内弹出。

除此之外还需要注意一点的是:

若相邻两关系是f0: start : t0,f1: start: t1,那么给0加入 t1 - t0

若为f0: end : t0,f1: start: t1,给当前栈顶元素加入t1 - t0

若为f0: start : t0,f0: end: t1 给f0加入 t1-t0+1

若为f0: start : t0,f1: end: t1 给f1加入 t1 - t0

时间复杂度O(n), 空间O(n) 

代码:

class Solution {
public:
    vector<int> exclusiveTime(int n, vector<string>& logs) {
        //we have to process every log string to find out the corresponding function and its start and end time
        //we can use 2 vectors to store the start time and end time and its id respectively, and sort it in ascending order
        vector<int> ret(n,0);
        if(logs.size() == 0) return ret;
        
        stack<int> funcStk;
        int lastTime = 0;
        bool lastEnd = true;
        for(auto l : logs){
            int idx1 = l.find(":");
            int idx2 = l.find(":", idx1+1);
            
            int id = stoi(l.substr(0, idx1));
            long time = stol(l.substr(idx2+1));
            
            bool isEnd = l.find("start") == string::npos;
            //std::cout << l << std::endl;
            int lastId = -1;
            if(!funcStk.empty()) lastId = funcStk.top();
            //std::cout << "cur top is " << lastId << std::endl;
            if(isEnd){
                funcStk.pop();
                if(lastEnd){
                    ret[id] += time - lastTime;
                }else{
                    ret[id] += time - lastTime+1;
                }
                //std::cout << id << " : " << ret[id] << std::endl;
            }else{
                if(!lastEnd){
                    ret[lastId] += time - lastTime;
                    //std::cout << lastId << " : " << ret[lastId] << std::endl;
                }else{
                    if(lastId != -1){
                        ret[lastId] += time - lastTime - 1;
                    }
                }
                funcStk.push(id);
            }
            lastTime = time;
            lastEnd = isEnd;
        }
        return ret;
    }
};
原文地址:https://www.cnblogs.com/yaoyudadudu/p/11741701.html