Day11 栈和队列

150. 逆波兰表达式求值

在这里插入图片描述

解法一:将计算部分抽象成一个函数,使代码更加简洁,避免了很多冗余操作。对比下面解法二(我自己写的),此解法(参考别人的)的代码更加精简。核心思想都是利用栈解决问题,遇到字符数字,则入栈,遇到运算符则将栈顶两元素退出来进行运算。那么如何判断是否是字符数字呢?这里用到了int()函数和try-except语句。如果是字符数字,用int()可以将其转换为数字,如果是运算符,使用int()则会报错,从而进入excep语句中。另外值得注意的是python的 b / a 会向下取整, 比如 -1 / 132 = -1。 题目要求是取整数部分,那么负数的时候,实际应该是向上取整, 解决方法: int(b / float(a))。python3 b / a 会转为小数计算,所以直接 int(b / a), 不能 b // a。

class Solution(object):
    def evalRPN(self, tokens):
        """
        :type tokens: List[str]
        :rtype: int
        """
        def calculate(num1, num2, op):
            if op == '+':
                return num1 + num2
            elif op == '-':
                return num2 - num1
            elif op == '*':
                return num1 * num2
            else:
                return int(num2 / float(num1))
        stack = []
        for token in tokens:
            try:
                stack.append(int(token))
            except:
                num1 = stack.pop()
                num2 = stack.pop()
                stack.append(calculate(num1, num2, token))
        return stack[0]

解法二:直接去判断i是何种运算符,反正就四种,其余情况都是数字呗。

class Solution(object):
    def evalRPN(self, tokens):
        """
        :type tokens: List[str]
        :rtype: int
        """
        stack = []
        ans = 0
        for i in tokens:
            if i == '+':
                ans = int(stack[-2]) + int(stack[-1])
                stack.pop()
                stack.pop()
                stack.append(ans)
            elif i == '-':
                ans = int(stack[-2]) - int(stack[-1])
                stack.pop()
                stack.pop()
                stack.append(ans)
            elif i == '*':
                ans = int(stack[-2]) * int(stack[-1])
                stack.pop()
                stack.pop()
                stack.append(ans)
            elif i == '/':
                ans = int(stack[-2]) / float(stack[-1])
                stack.pop()
                stack.pop()
                stack.append(ans)
            else:
                stack.append(i)
        return int(stack[0])

347. 前 K 个高频元素

在这里插入图片描述

解法一:用字典做哈希表,统计各个元素出现的频率,并根据出现的频率由高到低将字典排序。接着创建一个数组,将排好序的元素添加进数组,然后利用切片取出前k个元素。

如何让字典按值排序呢?这里回顾sorted函数的用法。(参考

  1. sorted高阶函数语法格式: sorted(可迭代对象,key=函数名,reverse=False/True)
 作用:从可迭代对象中,依次取出一个元素,该元素再按照key规定的排列依据排序。

 可迭代对象:即可依次取值的对象,例如:集合,序列(列表,字符串,元组),字典等。

 key : 是列表排列的依据,一般可以自定义一个函数返回排序的依据,再把函数名绑定给key。

 reverse : 译为反转,reverse默认等于False,从小到大排序。等于True时,从大到小排序。
  1. 匿名函数lambda的格式: 函数名 = lambda [形参1,形参2,…] : ,返回操作语句块产生的结果并绑定给函数名。
例如: key=lambda x : x[1]       

x:相当于字典集合中的一个元组, 例:dict_items([(3, 1), (1, 3), (2, 2)])中的(3, 1), (1, 3), (2, 2)

x[1]: 返回x中的第二个元素,即键值对元组中的值。dict_items([(3, 1), (1, 3), (2, 2)])中的1或2或3

注意:

(1) sorted函数中的可迭代对象不要用字典dic,那样只能迭代出的字典dic的键。要用dic.items()才可迭代出字典的键值对。

例:不能用 dic_order=sorted(dic,key=lambda x:x[1],reverse=False)

    要用 dic_order=sorted(dic.items(),key=lambda x:x[1],reverse=False)

(2) sorted函数排好序后,要绑定一个对象(赋值),例:dic_order=sorted(dic.items(),key=lambda x:x[1],reverse=False).

 因为字典是无序类型,用sorted函数排好序后不绑定dic_order,字典会自动打乱顺序。
dic={3:1,1:3,2:2}    # 首先建一个字典dic
 
#dic.items()返回的是: dict_items([(3, 1), (1, 3), (2, 2)])
 
dic_order=sorted(dic.items(),key=lambda x:x[1],reverse=True)  # 按字典集合中,每一个元组的第二个元素排列。x相当于字典集合中遍历出来的一个元组。

print(dic_order)     # 得到:  [(1, 3), (2, 2), (3, 1)]
class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        record = {}
        for i in nums:
            if record.get(i):
                record[i] += 1
            else:
                record[i] = 1
        record1 = sorted(record.items(), key=lambda x: x[1], reverse=True)
        print(record1)
        ans = []
        for item in record1:
            ans.append(item[0])
        return ans[:k]

解法二:堆队列算法-heapq模块以及其定义的函数。代码随想录中卡哥的讲解

heappush接受元组类型的参数,默认按照元组的第一个元素构成小根堆。参考:heapq模块学习

class Solution(object):
    def topKFrequent(self, nums, k):
        """
        :type nums: List[int]
        :type k: int
        :rtype: List[int]
        """
        import heapq
        # 统计每个元素出现的频率
        mapping = {}
        for i in nums:
            mapping[i] = mapping.get(i, 0) + 1
        
        # 定义一个小根堆对频率进行排序
        priority_que = []
        for key, freq in mapping.items():
            heapq.heappush(priority_que, (freq, key))
            if len(priority_que) > k: # 如果堆的大小大于k 则弹出 保证堆的大小为k
                heapq.heappop(priority_que)
        
        # 找出前k个高频元素 因为小根堆弹出最小的 所以倒序输出到数组
        res = [0] * k
        for i in range(k-1, -1, -1):
            res[i] = heapq.heappop(priority_que)[1]
        return res
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值