当前位置:   article > 正文

2024.6.13刷题记录

2024.6.13刷题记录

目录

一、828. 模拟栈 - AcWing题库

1.使用列表实现-摸鱼法

2.使用数组实现

二、AcWing 3302. 表达式求值 - AcWing

三、829. 模拟队列 - AcWing题库

四、830. 单调栈 - AcWing题库

五、154. 滑动窗口 - AcWing题库


一、828. 模拟栈 - AcWing题库

1.使用列表实现-摸鱼法

  1. # 使用列表实现
  2. '''
  3. push x – 向栈顶插入一个数 x;
  4. pop – 从栈顶弹出一个数;
  5. empty – 判断栈是否为空;
  6. query – 查询栈顶元素。
  7. '''
  8. def push(stack, x):
  9. stack.append(x)
  10. def pop(stack):
  11. stack.pop()
  12. def empty(stack):
  13. return 'YES' if len(stack) == 0 else 'NO'
  14. def query(stack):
  15. return stack[-1]
  16. if __name__ == '__main__':
  17. m = int(input())
  18. stack = []
  19. for _ in range(m):
  20. oper = input().split()
  21. if oper[0] == 'push':
  22. push(stack, int(oper[1]))
  23. elif oper[0] == 'pop':
  24. pop(stack)
  25. elif oper[0] == 'empty':
  26. print(empty(stack))
  27. else:
  28. print(query(stack))

2.使用数组实现

多用数组实现。

  1. # 使用数组实现
  2. def init(N = 100010):
  3. global stack, top
  4. stack = [0] * N
  5. top = 0 # 栈顶指针
  6. def push(x):
  7. global stack, top
  8. stack[top] = x
  9. top += 1
  10. def pop():
  11. global stack, top
  12. top -= 1
  13. def empty():
  14. global stack, top
  15. return 'YES' if top <= 0 else 'NO' # 栈顶指针同时代表有多少个元素
  16. def query():
  17. global stack, top
  18. return stack[top - 1]
  19. m = int(input())
  20. init()
  21. for _ in range(m):
  22. oper = input().split()
  23. if oper[0] == 'push':
  24. push(int(oper[1]))
  25. elif oper[0] == 'pop':
  26. pop()
  27. elif oper[0] == 'empty':
  28. print(empty())
  29. else:
  30. print(query())

二、AcWing 3302. 表达式求值 - AcWing

不会,思路来自题解(AcWing 3302. 表达式求值:多图讲解运算符优先级+详细代码注释 - AcWing),代码来自题解(AcWing 3302. 表达式求值 - AcWing)。

  1. dic = {'(': 0, '+': 1, "-": 1, '*': 2, '/': 2} # 优先级
  2. op = []
  3. num = []
  4. def new_eval():
  5. # 计算函数
  6. b = num.pop() # 注意弹出顺序
  7. a = num.pop()
  8. c = op.pop()
  9. if c == '+':
  10. x = a + b
  11. elif c == '-':
  12. x = a - b
  13. elif c == '*':
  14. x = a * b
  15. else:
  16. x = int(a / b) # 向0取整
  17. num.append(x) # 压回栈
  18. s = input()
  19. n = len(s)
  20. i = 0
  21. while i < n:
  22. c = s[i]
  23. if c.isdigit(): # 该函数检查字符是否为数字
  24. x = 0
  25. while i < n and s[i].isdigit():
  26. x = x * 10 + int(s[i])
  27. i += 1
  28. # 循环结束时为运算符,退回一次进入下一次判断
  29. i -= 1 # 重要
  30. num.append(x)
  31. elif c == '(':
  32. # 左括号直接入栈
  33. op.append('(')
  34. elif c == ')':
  35. # 弹出进行运算,直到遇见'('
  36. while op[-1] != '(':
  37. new_eval()
  38. op.pop() # 左括号不要
  39. else:
  40. # 运算符
  41. while len(op) and dic[op[-1]] >= dic[c]:
  42. # 当运算符栈顶优先级大于等于遇到的运算符
  43. # 弹出运算
  44. # 当栈顶为左括号时直接进
  45. new_eval()
  46. # 入栈
  47. op.append(c)
  48. i += 1
  49. # 栈内剩余元素运算
  50. while len(op):
  51. new_eval()
  52. print(num[-1]) # 最后的栈顶即为运算结果

三、829. 模拟队列 - AcWing题库

  1. def init(N = 100010):
  2. global queue, front, rear
  3. queue = [0] * N
  4. front = -1
  5. rear = -1
  6. def push(x):
  7. global queue, rear
  8. rear += 1
  9. queue[rear] = x
  10. def pop():
  11. global front
  12. front += 1
  13. def empty():
  14. global front, rear
  15. return "YES" if front >= rear else "NO"
  16. def query():
  17. global queue, front, rear
  18. return queue[front + 1]
  19. m = int(input())
  20. init()
  21. for _ in range(m):
  22. oper = input().split()
  23. if oper[0] == "push":
  24. push(int(int(oper[1])))
  25. elif oper[0] == "pop":
  26. pop()
  27. elif oper[0] == "empty":
  28. print(empty())
  29. else:
  30. print(query())

四、830. 单调栈 - AcWing题库

  1. n = int(input())
  2. nums = list(map(int, input().split()))
  3. st = [] # 维护左边的单调递增栈
  4. # ans = [-1] * n
  5. for i, x in enumerate(nums):
  6. ans = -1 # 节省储存空间
  7. while st and st[-1] >= x: # 维护单调递增
  8. st.pop()
  9. # if st: ans[i] = st[-1]
  10. if st: ans = st[-1]
  11. print(ans, end = ' ')
  12. st.append(x)
  13. # # 输出
  14. # for x in ans: print(x, end = ' ')

五、154. 滑动窗口 - AcWing题库

思路来自题解(AcWing 154. 滑动窗口---海绵宝宝来喽 - AcWing

当时没有想到怎么保证队内全都是窗口内的元素,答案:“当队头元素在窗口的左边的时候,弹出队头”,虽然不能保证队内一直没有窗口外的元素,但是能保证使用到的队内元素(队头)全是窗口内元素。当时是有想到这个方法的,但是以为不行,一下没转过来弯。

代码来自题解(AcWing 154. 滑动窗口 - AcWing

队列储存索引而不是元素,通过储存索引使我们能够快速判断元素是否出窗口。

  1. # 先进先出
  2. # 单调队列(本质上是双端队列)
  3. N = 1000010
  4. queue = [0] * N # 储存下标
  5. front, rear = 0, -1
  6. n, k = map(int, input().split())
  7. nums = list(map(int, input().split()))
  8. # 求最小值,单调递增队列
  9. for i, x in enumerate(nums):
  10. # 弹出队头越界值
  11. while front <= rear and i - k >= queue[front]:
  12. front += 1
  13. # 弹出末尾大于x的值,注意这里是值比较
  14. while front <= rear and nums[queue[rear]] > x:
  15. rear -= 1
  16. # 将rear放入末尾
  17. rear += 1
  18. queue[rear] = i # 注意这里是下标而不是值
  19. # 输出,注意这里是k - 1,因为第一个窗口也要输出
  20. if i >= k - 1:
  21. print(nums[queue[front]], end = ' ')
  22. print()
  23. front, rear = 0, -1 # 初始化
  24. # 求最大值,单调递减队列
  25. for i, x in enumerate(nums):
  26. # 队头弹出
  27. while front <= rear and i - k + 1 > queue[front]:
  28. front += 1
  29. # 队尾弹出,弹出操作均需要判断是否为空
  30. while front <= rear and nums[queue[rear]] < x:
  31. rear -= 1
  32. # 加入下标
  33. rear += 1
  34. queue[rear] = i
  35. # 输出
  36. if i >= k - 1:
  37. print(nums[queue[front]], end = ' ')

感谢你看到这里!一起加油吧!

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/不正经/article/detail/721338
推荐阅读
相关标签
  

闽ICP备14008679号