2.2.3 python数据结构之栈——应用(3)Leetcode题目解析

      接触了前面这么多题目后,我们应该对栈的思想有了深刻理解并提高了应用栈去解决问题、设计算法的能力,下面再看最后两道LeetCode的题目。第一题仍然是函数调用栈的应用,鄙人在学习了之前的题目后,终于可以亲自敲出来一道题目了,难度不大。第二道题是数组的问题,利用栈优化了算法,相信这一思路对其他问题也会有所启发。

636. Exclusive Time of Functions(函数的专有时间)

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.

题目解析:

像括号匹配一样,递归处理字符串,处理每一个完整的闭合的函数的时间,外部函数的时间要减去内部函数的时间。

class Solution:
    def exclusiveTime(self, n, logs):
        """
        :type n: int
        :type logs: List[str]
        :rtype: List[int]
        """
        def parse(log):
            id, con, time = log.split(':')
            id, time = int(id), int(time)
            se = 1 if con=='start' else 0
            return id, se, time
        
        def extime():
            log = logs.pop()        # 弹出start
            id, se, start_time = parse(log)
            id_, se, time_ = parse(logs[-1])
            inner = 0
            while not (id_ == id and se ==0) :
                t = extime()
                inner += t
                id_, se, time_ = parse(logs[-1])                                
            log = logs.pop()        # 弹出end
            id_, se, end_time = parse(log)
            t = end_time - start_time + 1
            res[id] += t - inner
            return  t        
        res = [0 for i in range(n)]                                  
        logs = logs[::-1]
        while logs:
            extime()
        return res

两个pop可以弹出对应的函数log,并相应得到开始和结束时间;注意的是返回的t和inner函数的作用,也是在提交后各种错误改进的。鄙人这一代码略有冗余,可以进行简化,说不定可以减小耗时。

503. Next Greater Element II(下一个更大的数)

iven a circular array (the next element of the last element is the first element of the array), print the Next Greater Number for every element. The Next Greater Number of a number x is the first greater number to its traversing-order next in the array, which means you could search circularly to find its next greater number. If it doesn't exist, output -1 for this number.
Example 1:
Input: [1,2,1]
Output: [2,-1,2]
Explanation: The first 1's next greater number is 2; 
The number 2 can't find next greater number; 

The second 1's next greater number needs to search circularly, which is also 2.

题目解析:

这道题很有趣,其实就是让数组循环,有两种方法,一是简单的O(n2)选择,但是鄙人写的python过不去最后的测试点,Java肯定是可以的。这一方法不再赘述,不是我们的重点,下面看这一利用栈的方法。

class Solution:
    def nextGreaterElements(self, nums):
        """
        :type nums: List[int]
        :rtype: List[int]
        """
        l = len(nums)        
        ans = [-1 for i in range(l)]
        
        stack = []
        for i in (range(l)[::-1]):
            stack.append(i)

        for i in (range(l)[::-1]):
            while stack and nums[stack[-1]]<=nums[i]:
                stack.pop()
            if stack:
                ans[i] = nums[stack[-1]]
            stack.append(i)        
        return ans            

利用栈存储大数的索引,建议自己举个栗子过一遍程序,有助于类似的问题的解决。这是栈和数组问题的综合,数组的问题多种多样,后面还会整合到一起学习一个。

 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值