150. 逆波兰表达式求值

感觉这个题目最难的部分就是:逆波兰表达式的优点,告诉我要怎么做,这样就很简单了。
注意下面的易错点:
-
写代码的时候先pop出来的数字作为减数和除数。
-
除法处是向0取整,python的除法是向下取整,不完全符合,要注意考虑:
math.ceil() 向0远离取整
round() 四舍五入
math.floor() 向下取整
// 同math.floor()
int() 向0靠近取整

python
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
stack = []
for i in tokens:
if i == '+':
# a = stack.pop()
# b = stack.pop()
# stack.append(b + a)
stack.append(stack.pop() + stack.pop())
elif i == '-':
a = stack.pop()
b = stack.pop()
stack.append(b - a)
# stack.append(stack.pop() + stack.pop())
elif i == '*':
a = stack.pop()
b = stack.pop()
stack.append(b * a)
elif i == '/':
a = stack.pop()
b = stack.pop()
stack.append(int(b / a))
else:
stack.append(int(i))
return stack[0]
239. 滑动窗口最大值

"困难"来了,直接吓哭了,跃跃欲试的一下就被超时哄睡了。
看了一遍思路,也是非常巧妙,知道要利用栈和队列实际上也没做出来。
这里补充一下双端队列的一些用法,之前一直用列表实现,也是发现吃了很多苦。
deque是Python标准库collections模块中的一个类,使用之前需要先导入模块:
from collections import deque2.1 创建deque对象
可以使用deque()函数来创建一个空的deque对象,也可以将一个可迭代对象转换为deque对象。下面是一些示例代码:
# 创建一个空的deque对象 d = deque() print(d) # 输出: deque([]) # 将一个可迭代对象转换为deque对象 s = "hello" d = deque(s) print(d) # 输出: deque(['h', 'e', 'l', 'l', 'o']) lst = [1, 2, 3] d = deque(lst) print(d) # 输出: deque([1, 2, 3])从上面的代码可以看出,deque对象可以存储任意类型的元素。
2.2 deque对象的操作
deque对象支持一系列的操作,包括添加元素、删除元素、访问元素等。
2.2.1 添加元素
可以使用append()函数在deque的右侧添加元素,也可以使用appendleft()函数在deque的左侧添加元素。示例代码如下:
d = deque([1, 2, 3]) d.append(4) print(d) # 输出: deque([1, 2, 3, 4]) d.appendleft(0) print(d) # 输出: deque([0, 1, 2, 3, 4])2.2.2 删除元素
可以使用pop()函数从deque的右侧删除元素,并返回删除的元素。类似地,可以使用popleft()函数从deque的左侧删除元素,并返回删除的元素。示例代码如下:
d = deque([0, 1, 2, 3, 4]) x = d.pop() print(x) # 输出: 4 print(d) # 输出: deque([0, 1, 2, 3]) y = d.popleft() print(y) # 输出: 0 print(d) # 输出: deque([1, 2, 3])2.2.3 访问元素
可以使用索引或者切片来访问deque对象中的元素。示例代码如下:
d = deque([0, 1, 2, 3]) print(d[0]) # 输出: 0 print(d[-1]) # 输出: 3 print(d[1:3]) # 输出: deque([1, 2])2.3 deque的其他常用函数和属性
除了上述的基本用法,deque还提供了一些常用的函数和属性,下面我们来逐个介绍。
2.3.1 extend()和extendleft()函数
extend()函数用于在deque的右侧添加多个元素,extendleft()函数用于在deque的左侧添加多个元素。示例代码如下:
d = deque([1, 2, 3]) d.extend([4, 5, 6]) print(d) # 输出: deque([1, 2, 3, 4, 5, 6]) d.extendleft([0, -1, -2]) print(d) # 输出: deque([-2, -1, 0, 1, 2, 3, 4, 5, 6])2.3.2 rotate()函数
rotate()函数用于将deque对象中的元素向右循环移动n个位置,n可以是负数。示例代码如下:
d = deque([1, 2, 3, 4, 5, 6]) d.rotate(2) print(d) # 输出: deque([5, 6, 1, 2, 3, 4]) d.rotate(-2) print(d) # 输出: deque([1, 2, 3, 4, 5, 6])2.3.3 count()函数
count()函数用于返回deque对象中指定元素的个数。示例代码如下:
d = deque([1, 2, 2, 3, 3, 3]) print(d.count(2)) # 输出: 22.3.4 remove()函数
remove()函数用于删除deque对象中第一次出现的指定元素。如果元素不存在,则会抛出ValueError。示例代码如下:
d = deque([1, 2, 3, 2, 3, 4]) d.remove(2) print(d) # 输出: deque([1, 3, 2, 3, 4])2.3.5 maxlen属性
maxlen属性用于获取或设置deque对象的最大长度。如果deque对象的长度超过了最大长度,那么在执行插入操作时将自动删除最左侧的元素。示例代码如下:
d = deque([1, 2, 3], maxlen=3) print(d.maxlen) # 输出: 3 d.append(4) print(d) # 输出: deque([2, 3, 4], maxlen=3)
首先定义一个双端队列,再定义一个列表用来存储每一个滑动窗口的最大值。
思路是这样,使用一个队列来存储维护滑动窗口的最大值,使得每次都可以在队列的左侧,也即头部获取到最大值。也即当前输入的这个值大于队列尾部的那个值时,此刻,如果需要计算最大值,那么队列尾部那个小一点的值就无需维护,故对其尾部所有小于当前值的值进行pop,然后append这个值。另外,当当前队列左侧的最大值即将滑动走,也即nums[i-k] == q[0]时,那么这个时候要popleft,把队列头部更新。完成这些任务后,对于k-1后面的行动,给maxlist输入一个最大值,形成列表。
python
from collections import deque
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
q = deque()
maxlist = []
for i in range(len(nums)):
while q and nums[i] > q[-1]:
q.pop()
q.append(nums[i])
if i >= k and nums[i-k] == q[0]:
q.popleft()
if i >= k-1:
maxlist.append(q[0])
return maxlist
347.前 K 个高频元素

实际上思路还是很好理解的,能想到先用字典把频率算好,然后对频率排序去除前k个大的,只不过苦于难以实现。
实际上这里对于堆的实现没有学习,需要复习在看。因为明天休息,明天打算对python的数据结构实现和应用基础进行总结
python
import heapq
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
index = {}
for i in range(len(nums)):
index[nums[i]] = index.get(nums[i], 0) + 1
que = []
for key, val in index.items():
heapq.heappush(que,(val, key))
if len(que) > k:
heapq.heappop(que)
result = [0]*k
for i in range(k-1,-1,-1):
result[i] = heapq.heappop(que)[1]
return result
总结
需要做技术和方法上面的总结还是