代码随想录算法训练营day13 | 150. 逆波兰表达式求值,239. 滑动窗口最大值,347.前 K 个高频元素

题目:

  • 150. 逆波兰表达式求值

    • 注意:The integer division should truncate toward zero, which means losing its fractional part. For example, 8.345 would be truncated to 8, and -2.7335 would be truncated to -2.

    • 对于truncate to zero的处理,python3和python2是有区别的!

      • int(a/b)在python3中是可以的,也可以用math.trunc(a/b),但在python2不可以。
    • 当需要container的时候,总是习惯直接用数组,缺少对于复杂度的考量,尤其是直接ac之后更不会继续思考。这里就是set更快!

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        
        stack = []
        
        for token in tokens:
            if token not in {'+', '-', '*', '/'}: # O(1) 查找
                stack.append(int(token))
                
            else:
                b = stack.pop()
                a = stack.pop()
                if token == '+':
                    stack.append(a+b)
                elif token == '-':
                    stack.append(a-b)
                elif token == '*':
                    stack.append(a*b)
                elif token == '/':
                    stack.append(int(a/b))
                    
        return stack[-1]
        

我们习惯看到的表达式都是中缀表达式,因为符合我们的习惯,但是中缀表达式对于计算机来说就不是很友好了。

例如:4 + 13 / 5,这就是中缀表达式,计算机从左到右去扫描的话,扫到13,还要判断13后面是什么运算法,还要比较一下优先级,然后13还和后面的5做运算,做完运算之后,还要向前回退到 4 的位置,继续做加法,你说麻不麻烦!

那么将中缀表达式,转化为后缀表达式之后:["4", "13", "5", "/", "+"] ,就不一样了,计算机可以利用栈里顺序处理,不需要考虑优先级了。也不用回退了, 所以后缀表达式对计算机来说是非常友好的。

  • 239. 滑动窗口最大值(hard)

    • 第一反应就是暴力解法,直接for循环,但是超时,O(n*k).

    • 考虑O(n)解法:通过视频讲解知道需要用单调递减队列(monotonically decreasing queue)

  1. 单调队列正式登场!| LeetCode:239. 滑动窗口最大值_哔哩哔哩_bilibili
  2. https://www.youtube.com/watch?v=DfljaUwZsOk
  • Q1: 为什么用队列而不是栈?
  • S:因为需要在beginning的位置进行增删操作,队列可以做到O(1).
  • Q2: 如下题解为什么使用deque而不是list来实现队列?
  • S:在day11 blog中有总结。
class Solution(object):
    def maxSlidingWindow(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        
        # time O(n) + space O(k)
        
        ans = []
        queue = collections.deque() #this queue is to store index not value
        left = right = 0 #tell where the current window is
        
        while right < len(nums):
            #the below while loop is 
            #to make sure no smaller values(compare to nums[right]) in the queue, 
            #to pop smaller values
            while len(queue) != 0 and nums[queue[-1]] < nums[right]: 
                queue.pop() 
            queue.append(right)
            
            #remove left value from the window
            if left > queue[0]:
                queue.popleft()
            
            if right+1 >= k:
                ans.append(nums[queue[0]])
                left += 1
            
            right += 1
        
        return ans
  • 347.前 K 个高频元素(medium)

  • 题解1:

    • 第一反应是用dict,也就是hashmap,通过出现的次数来找出对应的前k个key(也就是nums里的值)

    • trick: Get key by value in dictionary

class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        temp = {}
        for num in nums:
            if num not in temp:
                temp[num] = 1
            else:
                temp[num] += 1
        
        ans = []
        for i in range(k):
            max_key_by_value = list(temp.keys())[list(temp.values()).index(max(temp.values()))]
            temp[max_key_by_value] = 0
            ans.append(max_key_by_value)
        
        return ans

复杂度分析:(to be finished...)

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        
        count = {}
        freq = [[] for i in range(len(nums) + 1)]
        
        for num in nums:
            if num not in count:
                count[num] = 1
            else:
                count[num] += 1
        print(count)
        print(count.items())
        
        for num, c in count.items():
            freq[c].append(num)  
        print(freq)
        
        ans = []
        for i in range(len(freq)-1, 0, -1):
            for num in freq[i]:
                ans.append(num)
                if len(ans) == k:
                    return ans
  • 题解3: O(nlogk) + O(n)     (还没搞懂,弄懂了再贴到下面。。。)

总结:

  1. 单调队列的思路还需仔细琢磨

  2. 大小顶堆的概念不熟悉,需要单独学习一下。

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

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值