leetcode极速复习版-第五章栈与队列

news2024/11/17 5:47:42

目录

栈与队列

理论基础

232.用栈实现队列

225. 用队列实现栈

20. 有效的括号

1047. 删除字符串中的所有相邻重复项

150. 逆波兰表达式求值

239.滑动窗口最大值

347.前 K 个高频元素


栈与队列

理论基础

队列是先进先出,栈是先进后出。

232.用栈实现队列

使用栈实现队列的下列操作:

push(x) -- 将一个元素放入队列的尾部。

pop() -- 从队列首部移除元素。

peek() -- 返回队列首部的元素。

empty() -- 返回队列是否为空。

class MyQueue:
 
    def __init__(self):
        """
        in主要负责push,out主要负责pop
        """
        self.stack_in = []
        self.stack_out = []
# python的list像栈,先入后出。需要实现队列,先入先出。
# ✔
 
    def push(self, x: int) -> None:
        """
        有新元素进来,就往in里面push
        """
        self.stack_in.append(x)
# ✔
 
    def pop(self) -> int:
        """
        Removes the element from in front of queue and returns that element.
        """
        if self.empty():
            return None
        # if self.stack_in:
        #     for i in range(len(self.stack_in)):
        #         self.stack_out.append(self.stack_in.pop())
        # return self.stack_out.pop()
# 以上会出错,例如:
# ["MyQueue","push","push","push","push","pop","push","pop","pop","pop","pop"]
# [[],[1],[2],[3],[4],[],[5],[],[],[],[]]
# 输出
# [null,null,null,null,null,1,null,5,2,3,4]
# 预期结果
# [null,null,null,null,null,1,null,2,3,4,5]
# push[5]时,基于先入先出的原则,[5]应该最后被pop出来。但按照上面的错误流程,在out已经有值的情况下,[5]还是会被从in转移到out然后被先pop出来。
# 正确应该是先把out里的全pop完然后再把[5]从in转移到out然后pop。
        if self.stack_out:
            return self.stack_out.pop()
        else:
            for i in range(len(self.stack_in)):
                self.stack_out.append(self.stack_in.pop())
            return self.stack_out.pop()
        
# 为什么上面有self.stack_out.pop(),下面有self.pop(),这两个有什么区别?
# 区别在于,self.stack_out.pop()调用的不是我们在这里定义的pop函数。它调用的是stack_out作为list类的库函数,
# 是list类固有的。每个list都有,随便新定义一个list,它也可以用.pop方法,返回的是list最末位的元素。
# 例如 定义list0 = [1,2,3,4],要求return list0.pop(), list0,返回值为[4,[1,2,3]]
# 下面的self.pop()是调用我们在这里定义的pop函数。
    def peek(self) -> int:
        """
        Get the front element.
        """
        ans = self.pop()
        self.stack_out.append(ans)
        return ans
        
 
    def empty(self) -> bool:
        """
        只要in或者out有元素,说明队列不为空
        """
        return not (self.stack_in or self.stack_out)

225. 用队列实现栈

使用队列实现栈的下列操作:

push(x) -- 元素 x 入栈

pop() -- 移除栈顶元素

top() -- 获取栈顶元素

empty() -- 返回栈是否为空

注意:

你只能使用队列的基本操作-- 也就是 push to back, peek/pop from front, size, 和 is empty 这些操作是合法的。

你所使用的语言也许不支持队列。 你可以使用 list 或者 deque(双端队列)来模拟一个队列 , 只要是标准的队列操作即可。

你可以假设所有操作都是有效的(例如, 对一个空的栈不会调用 pop 或者 top 操作)。

class MyStack:
 
    def __init__(self):
        self.que = deque()
 
    def push(self, x: int) -> None:
        self.que.append(x)
 
    def pop(self):
        if self.empty():
            return None
        # for i in range(len(self.que) - 1):
        #     self.que.append(self.que.pop()) # 错误的。deque()的pop()是先入后出的pop
        #     # 例如[1,2,3],pop()返回的是3而不是想象中的1.
        #     # 所以上式直接是,pop3然后push3然后pop2然后push2,最后deque还是没变。。
        #     # 应该用popleft()实现队列的先入先出,[1,2,3]返回1.
        for i in range(len(self.que) - 1):
            self.que.append(self.que.popleft())
        return self.que.popleft()
 # 这里的操作比较单纯暴力的
    def top(self) -> int:
        if self.empty():
            return None
        return self.que[-1]
 
    def empty(self) -> bool:
        if self.que != deque():
            return False
        else:
            return True
        # 也可以用下面这个来判断,更简单直接    
        # return not self.que

20. 有效的括号

给定一个只包括 '(',')','{','}','[',']' 的字符串,判断字符串是否有效。

有效字符串需满足:

左括号必须用相同类型的右括号闭合。

左括号必须以正确的顺序闭合。

注意空字符串可被认为是有效字符串。

示例 1:

输入: "()"

输出: true

示例 2:

输入: "()[]{}"

输出: true

示例 3:

输入: "(]"

输出: false

示例 4:

输入: "([)]"

输出: false

示例 5:

输入: "{[]}"

输出: true

括号匹配是使用栈解决的经典问题。

先来分析一下 这里有三种不匹配的情况,

  1. 第一种情况,字符串里左方向的括号多余了 ,所以不匹配。 
  2. 第二种情况,括号没有多余,但是 括号的类型没有匹配上。 
  3. 第三种情况,字符串里右方向的括号多余了,所以不匹配。 
class Solution:
    def isValid(self, s: str) -> bool:
        st = []
        for i in range(len(s)):
            if s[i] == '(':
                st.append(')')
            elif s[i] == '{':
                st.append('}')
            elif s[i] == '[':
                st.append(']')
            elif st == [] or s[i] != st[-1]:
                return False
            else:
                st.pop()
        return False if st else True

算法题做题前先想想能不能第一步先剪枝。降低计算量。

修改后在开头增加剪枝的两行,判断字符串长度是否为单数,若为单数则必不可能全成对。

if len(s) % 2 != 0:

return False

可改进:

for i in range(len(s)):换成 for item in s:

elif st == []换成 elif not st

1047. 删除字符串中的所有相邻重复项

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

示例:

输入:"abbaca"

输出:"ca"

解释:例如,在 "abbaca" 中,我们可以删除 "bb" 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 "aaca",其中又只有 "aa" 可以执行重复项删除操作,所以最后的字符串为 "ca"。

提示:

1 <= S.length <= 20000

S 仅由小写英文字母组成。

本题是匹配相邻元素,最后都是做消除的操作。

本题也是用栈来解决的经典题目。

从栈中弹出剩余元素,此时是字符串ac,因为从栈里弹出的元素是倒序的,所以再对字符串进行反转一下,就得到了最终的结果。

class Solution:
    def removeDuplicates(self, s: str) -> str:
        res = []
        for item in s:
            if not res or item != res[-1]:#为空或值不同则增
                res.append(item)
            else:#值同则消
                res.pop()
        return ''.join(res)
150. 逆波兰表达式求值

根据 逆波兰表示法,求表达式的值。

有效的运算符包括 + ,  - ,  * ,  / 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。

说明:

整数除法只保留整数部分。 给定逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

  • 两个整数之间的除法总是 向零截断 。
  • 表达式中不含除零运算。
  • 输入是一个根据逆波兰表示法表示的算术表达式。
  • 答案及所有中间计算结果可以用 32 位 整数表示。

向零取整(向零截断) 取距离0最近的精确整数值。

示例 1:

输入: ["2", "1", "+", "3", " * "]

输出: 9

解释: 该算式转化为常见的中缀算术表达式为:((2 + 1) * 3) = 9

示例 2:

输入: ["4", "13", "5", "/", "+"]

输出: 6

解释: 该算式转化为常见的中缀算术表达式为:(4 + (13 / 5)) = 6

示例 3:

输入: ["10", "6", "9", "3", "+", "-11", " * ", "/", " * ", "17", "+", "5", "+"]

输出: 22

解释:该算式转化为常见的中缀算术表达式为:

((10 * (6 / ((9 + 3) * -11))) + 17) + 5       

= ((10 * (6 / (12 * -11))) + 17) + 5       

= ((10 * (6 / -132)) + 17) + 5     

= ((10 * 0) + 17) + 5     

= (0 + 17) + 5    

= 17 + 5    

= 22    

逆波兰表达式:是一种后缀表达式,所谓后缀就是指运算符写在后面。

平常使用的算式则是一种中缀表达式,如 ( 1 + 2 ) * ( 3 + 4 ) 。

该算式的逆波兰表达式写法为 ( ( 1 2 + ) ( 3 4 + ) * ) 。

逆波兰表达式主要有以下两个优点:

去掉括号后表达式无歧义,上式即便写成 1 2 + 3 4 + * 也可以依据次序计算出正确结果。

适合用栈操作运算:遇到数字则入栈;遇到运算符则取出栈顶两个数字进行计算,并将结果压入栈中。

其实逆波兰表达式相当于是二叉树中的后序遍历。 大家可以把运算符作为中间节点,按照后序遍历的规则画出一个二叉树。

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        res = []
        for item in tokens:
            if item == '+' or item == '-' or item == '*' or item == '/':
                nums1 = res.pop()
                nums2 = res.pop()
                if item == '+':
                    res.append(nums1 + nums2)
                if item == '-':
                    res.append(nums2 - nums1)
                    # 注意不是nums1 - nums2 因为pop的顺序
                if item == '*':
                    res.append(nums1 * nums2)
                if item == '/':
                    # res.append(nums2 // nums1)
                    # 上式不对。例如6/(-132)结果本来应该是0但是这个除法(//)(也称地板除)会得到-1的结果。正确应该是:
                    res.append(int(nums2 / nums1))
            else:
                res.append(int(item))
        return res.pop()

eval()是python中功能非常强大的一个函数

将字符串当成有效的表达式来求值,并返回计算结果

所谓表达式就是:eval这个函数会把里面的字符串参数的引号去掉,把中间的内容当成Python的代码,eval函数会执行这段代码并且返回执行结果

stack.append( int(eval(f'{second_num} {item} {first_num}'))) 

239.滑动窗口最大值

给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

进阶:

你能在线性时间复杂度内解决此题吗?

提示:

1 <= nums.length <= 10^5

-10^4 <= nums[i] <= 10^4

1 <= k <= nums.length

这是使用单调队列的经典题目。

难点是如何求一个区间里的最大值呢? (这好像是废话),暴力一下不就得了。

暴力方法,遍历一遍的过程中每次从窗口中再找到最大的数值,这样很明显是O(n × k)的算法。

分析一下,队列里的元素一定是要排序的,而且要最大值放在出队口,要不然怎么知道最大值呢。

但如果把窗口里的元素都放进队列里,窗口移动的时候,队列需要弹出元素。

那么问题来了,已经排序之后的队列 怎么能把窗口要移除的元素(这个元素可不一定是最大值)弹出呢。

其实队列没有必要维护窗口里的所有元素,只需要维护有可能成为窗口里最大值的元素就可以了,同时保证队列里的元素数值是由大到小的。

那么这个维护元素单调递减的队列就叫做单调队列,即单调递减或单调递增的队列。

对于窗口里的元素{2, 3, 5, 1 ,4},单调队列里只维护{5, 4} 就够了,保持单调队列里单调递减,此时队列出口元素就是窗口里最大元素。

进2:2

进3:3

进5:5

进1:5 1

进4:5 4

后来的大的吃小的

后来的小的保留下

设计单调队列的时候,pop,和push操作要保持如下规则:

  1. pop(value):如果窗口移动的时候左侧pop的元素的value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作。此时单调队列继续往后增加值而不弹出值
  2. push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,并继续移动滑窗,若push进滑窗的是小值则保留在单调队列里。
# deque 是Python标准库 collections 中的一个类,实现了两端都可以操作的队列,相当于双端队列
# append(item),添加一个数据到队列的尾部。与列表的append()方法功能相似。
# appendleft(item),添加一个数据到队列的头部。与append()的添加方向相反。
# pop(),将队列尾部的数据弹出,并作为返回值。
# popleft(),将队列头部的数据弹出,并作为返回值。
class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        
        # 视频里讲的是左边pop出,右边push进(但push进的时候涉及右边出和进 视频里用push_back和pop_back),左边大右边小
        # 这里尝试右边pop出,左边push进(但涉及appendleft和popleft),左边小右边大
        def pop(que, val): #(右出)
            # 如果没有这个if条件会怎样。因为但凡是需要pop的好像都是pop最大值
            # 回答:必须要有if。否则,比如-1 3 1 -3,滑动到3 1 -3的时候要pop出-1,但此时-1已经被3卷走了,所以滑动窗口里本来也没-1,因此不需要进行pop操作。
            # if not que and que[-1] == val: 判断条件不是not que而是que,表示que不是空而是有值的时候
            if que and que[-1] == val: # 此时pop的就是当前窗口最大值
                que.pop()
            return que
        
        def push(que, val): # (左出左进)
            while que and que[0] < val:
                que.popleft()
            que.appendleft(val)
            return que
        que = deque()
        res = []
        for i in range(len(nums)):
            if i < k:
                que = push(que, nums[i])
            else:
                res.append(que[-1])
                # 注意append是用小括号()而不是中括号[]
                que = push(que, nums[i])
                que = pop(que, nums[- k])
                # 上两行交换会否有影响?不能交换,要先push再pop,否则可能push进的是当前窗口的最大值但由于pop先于push,导致pop的还是上一个窗口的最大值。
        res.append(que[-1])
        return res
          
 
        
# 下面是卡哥的
# from collections import deque
# class MyQueue: #单调队列(从大到小
#     def __init__(self):
#         self.queue = deque() #这里需要使用deque实现单调队列,直接使用list会超时
    
#     #每次弹出的时候,比较当前要弹出的数值是否等于队列出口元素的数值,如果相等则弹出。
#     #同时pop之前判断队列当前是否为空。
#     def pop(self, value):
#         if self.queue and value == self.queue[0]:
#             self.queue.popleft()#list.pop()时间复杂度为O(n),这里需要使用collections.deque()
            
#     #如果push的数值大于入口元素的数值,那么就将队列后端的数值弹出,直到push的数值小于等于队列入口元素的数值为止。
#     #这样就保持了队列里的数值是单调从大到小的了。
#     def push(self, value):
#         while self.queue and value > self.queue[-1]:
#             self.queue.pop()
#         self.queue.append(value)
        
#     #查询当前队列里的最大值 直接返回队列前端也就是front就可以了。
#     def front(self):
#         return self.queue[0]
    
# class Solution:
#     def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
#         que = MyQueue()
#         result = []
#         for i in range(k): #先将前k的元素放进队列
#             que.push(nums[i])
#         result.append(que.front()) #result 记录前k的元素的最大值
#         for i in range(k, len(nums)):
#             que.pop(nums[i - k]) #滑动窗口移除最前面元素
#             que.push(nums[i]) #滑动窗口前加入最后面的元素
#             result.append(que.front()) #记录对应的最大值
#         return result
347.前 K 个高频元素

给定一个非空的整数数组,返回其中出现频率前 k 高的元素。

示例 1:

输入: nums = [1,1,1,2,2,3], k = 2

输出: [1,2]

示例 2:

输入: nums = [1], k = 1

输出: [1]

提示:

你可以假设给定的 k 总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。

你的算法的时间复杂度必须优于 $O(n \log n)$ , n 是数组的大小。

题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的。

你可以按任意顺序返回答案。

这道题目主要涉及到如下三块内容:

  1. 要统计元素出现频率
  2. 对频率排序
  3. 找出前K个高频元素

首先统计元素出现的频率,这一类的问题可以使用map来进行统计。

然后是对频率进行排序,这里我们可以使用一种 容器适配器就是优先级队列

堆是一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。

所以大家经常说的大顶堆(堆头是最大元素),小顶堆(堆头是最小元素)

我们要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。

# 以下为自己学完之后写的版本
import heapq
class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        map_ = {}
        for item in nums:
            map_[item] = map_.get(item, 0) + 1
            # map_.get(item, 0)表示若有item则返回item否则返回0
        pri_que = []
        # for (key, freq) in map_: ✖
        for (key, freq) in map_.items():
            if len(pri_que) < k:
                heapq.heappush(pri_que, (freq, key))
            else:
                heapq.heappush(pri_que, (freq, key))
                heapq.heappop(pri_que)
                # 必须先push再pop,否则不对。
        return [i[1] for i in pri_que]
 
# # python内置模块 --- heapq:实现了一个小根堆。
# # 模块内常见的操作函数:
# # 1. heapify(x) :    将列表x转换为堆(小根堆)。
# # 2. heappush(heap,item): 将item压入堆中。(heap使存放堆的数组)
# # 3. heappop(heap): 从堆中弹出最小的项,并将其值返回。
# # heapq堆数据结构最重要的特征是heap[0]永远是最小的元素
# # ————————————————
# # heapq.heapify(list)
# # 将列表转换为最小堆 ,转换完后仍然是列表,所以heapify只是对列表中的元素进行了堆属性的排序
 
# # import heapq
# # res=[7,1,5,4,2,3]
# # print("列表",res,type(res))     #列表 [7, 1, 5, 4, 2, 3] 
# # heapq.heapify(res)
# # print("最小堆",res,type(res))   #最小堆 [1, 2, 3, 4, 7, 5] 
# # ————————————————
# # heapq.heappush(heap, item)
# # 将元素item压入heap堆(列表)中
 
# # import heapq
# # res=[7,1,5,6,2,3]
# # heapq.heapify(res)
# # heapq.heappush(res,8)
# # print("最小堆",res,type(res))   #最小堆 [1, 2, 3, 6, 7, 5, 8] 
# # ————————————————
# # heapq.heappop(heap) 
# # 删除并返回最小值,因为堆的特征是heap[0]永远是最小的元素,所以一般都是删除第一个元素。故,需要先通过heapify(list) 将list转变为heap。
 
# # import heapq
# # res=[7,1,5,6,2,3]
# # print("列表",res,type(res))      #列表 [7, 1, 5, 6, 2, 3] 
# # heapq.heapify(res)
# # min_d=heapq.heappop(res)
# # print(min_d)                     #1
# # print("最小堆",res,type(res))    #最小堆 [2, 5, 3, 6, 7] 

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/728541.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

动态路由,微信小程序绑定

■登录成功之后添加动态路由 ●登录的时候会获取到它的菜单配置■动态路由 | Vue Router <view wx:for"{{list}}">{{index}}--- {{item.name}} </view><view wx:for"{{list}}" wx:for-item "ttt" wx:for-index"num"&…

第二节 给SpringBootAdmin的server端加入spring security安全控制

前言 本来想用一节就写完SpringBootAdmin的&#xff0c;但随着研究的深入发现一节应该是不够的&#xff0c;网上的资料也不会非常系统&#xff0c;官网的例子有些已经好几年没更新了&#xff0c;所以接下来还是系统性的来写下吧 第一节 完成基础配置&#xff0c;暴露所有端点…

Qt-->QQ登陆界面图形化界面

#include "mainwindow.h" #include "ui_mainwindow.h"MainWindow::MainWindow(QWidget *parent) :QMainWindow(parent),ui(new Ui::MainWindow) {ui->setupUi(this);this->setFixedSize(640,520);//设置窗口标题this->setWindowTitle("QQ&qu…

勒索病毒危害,企业该如何预防勒索病毒

勒索病毒是一种恶意软件&#xff0c;它会对企业内的计算机系统或数据进行加密或锁定&#xff0c;并要求企业支付赎金以解锁或解密。 勒索病毒危害&#xff1a; 数据丢失&#xff1a;勒索病毒可以加密您的文件、照片、视频和其他重要数据&#xff0c;使其无法访问或恢复。如果…

解决centos7和主机win11不能互传文件复制粘贴;及CentOS7最小安装版 VMware Tools安装

linux.iso 中的文件已经加载到 /mnt/cdrom 目录下了。在 /mnt/cdrom 中找到加载出来的文件并拷贝到 /tmp目录下&#xff0c;进行解压。解压好后从中找到 vmware-install.pl&#xff0c;这是vmware tools的安装文件&#xff0c;执行此文件开始安装 ./vmware-install.pl 一路Ente…

宏基因组碳循环高分分析思路,你值得拥有!

碳是生命物质中的主要元素之一&#xff0c;是有机质的重要组成部分。地球上主要有四大碳库&#xff0c;即大气碳库&#xff0c;海洋碳库、陆地生态系统碳库和岩石圈碳库。碳循环&#xff0c;是指碳元素在自然界的循环状态&#xff0c;大气中的二氧化碳&#xff08;CO2&#xff…

Shamir秘密共享

目录 Shamir秘密共享 秘密共享的概念 问题1: 问题2: 秘密分割门限方案的定义 Shamir秘密共享方案 组成 构造思路 构造 计算f(x) 例1 例2 二、GMW方案 Shamir秘密共享 秘密共享的概念 问题1: 保险柜中存放有10个人的共有财产&#xff0c;要从保险柜中取出物品&am…

【Python编程系列】5、变量

作用 变量用来存储数据: a = 10使用规则 python作为解释型,属于弱类型和动态型语言。它不需要强制声明变量的数据类型,因为它不需要编译。一般要编译的语言需要明确所有的东西,只有这样才能编译成二进制文件。 由于不需要声明数据类型,那么在声明变量时会一并赋值: …

什么是serialVersionUID?为什么要使用它?

目录 一、什么是serialVersionUID二、创建一个serialVersionUID三、使用 serialVersionUID3.1 序列化实例程序3.2 反序列化实例程序3.3 serialVersionUID不同的情况下进行序列话和反序列化3.4 能不能不提供serialVersionUID&#xff1f; 一、什么是serialVersionUID SerialVer…

Dubbo hystrix 熔断降级 详细示例 多服务 公共api

目录 介绍 demo-api pom 目录 代码api provider 服务提供者 目录 pom 服务实现代码 启动代码 配置 日志 consumer 消费者 目录 pom 调用service接口 调用serviceImpl类 ctr 配置 页面调用熔断效果 相关文章 介绍 因为网上和官网拷贝的文档发现有很多版本…

axios拦截器和token

axios拦截器 ​​ 在请求或响应被 then 或 catch 处理前拦截它们。 // 添加请求拦截器 axios.interceptors.request.use(function (config) {// 在发送请求之前做些什么return config;}, function (error) {// 对请求错误做些什么return Promise.reject(error);});// 添加响应…

阿里云国际站代理商:阿里巴巴的阿里云到底是做什么用的,怎么我们普通人不理解,也不知道是怎么样一种服务?

阿里巴巴的阿里云到底是做什么用的&#xff0c;怎么我们普通人不理解&#xff0c;也不知道是怎么样一种服务&#xff1f;   阿里巴巴的阿里云&#xff0c;不只是一个名字——打通理解的迷宫   面对朝日逐极而生的科技天光&#xff0c;阿里巴巴如一座灯塔引领者我们向前。然…

openGauss学习笔记-02 openGauss系统架构

文章目录 openGauss学习笔记-02 openGauss系统架构2.1 软件架构2.1.1 逻辑架构2.1.2 逻辑架构说明 openGauss学习笔记-02 openGauss系统架构 openGauss是单机系统&#xff0c;在这样的系统架构中&#xff0c;业务数据存储在单个物理节点上&#xff0c;数据访问任务被推送到服务…

nginx七层代理和四层转发的理解

先来理解一下osi七层模型 应用层 应用层是ISO七层模型的最高层&#xff0c;它直接与用户和应用程序交互&#xff0c;提供用户与网络的接口。它包括各种应用协议&#xff0c;如HTTP、FTP、SMTP等&#xff0c;用于实现特定应用的功能和通信表示层 表示层…

鉴机:粉丝买了一台宝峰uv5r对讲机,竟是假的?

最近有粉丝在某宝上购买了一台uv5r对讲机&#xff0c;回来拆盒后发现有点不对劲&#xff0c;甚至连logo都没有&#xff0c;请各位鉴别一下&#xff0c;看看是真的还是假的。 网友买的uv5r对讲机 其他网友看完后几乎一致认为是假的&#xff0c;有人还贴出来比对照片&#xff1a…

系统版本由Centos7.9恢复到RedHat7.5

问题描述 安装nginx的时候无法联网&#xff0c;通过rpm包进行的安装&#xff0c;打包编译时使用的部分依赖包是centos的资源&#xff0c;导致安装后系统版本由之前的RedHat7.5变成了centos7.9。现需恢复到之前的系统版本。 解决方法 将之前安装的centos资源包删除&#xff0c…

GBASE智赋城轨再下一城!兰州轨道交通2号线开通试运营

“欢迎乘坐兰州轨道交通2号线……”6月29日上午9时36分&#xff0c;伴随一阵悦耳的播报声&#xff0c;兰州轨道交通2号线一期工程开通试运营&#xff0c;面向社会开放。 兰州轨道交通2号线一期工程全长9.06公里&#xff0c;共设置9座车站&#xff0c;2号线的开通试运营宣告兰州…

倍量过左峰选股公式,找到起爆点

左峰简单来说就是前期拉升形成的波段高点&#xff0c;左峰之后是回调&#xff0c;形成凹口&#xff0c;过左峰就是突破前期波段高点。从左峰的数量上&#xff0c;有过一峰、二峰、三峰等&#xff1b;从量价上&#xff0c;有倍量过左峰、缩量过左峰等。本文编写倍量过左峰选股公…

Ubuntu:修改ssh端口并开放防火墙

Ubuntu开放防火墙并修改ssh端口 1、概述2、修改ssh端口并启用防火墙2.1、 修改ssh端口2.2、开启防火墙2.3、端口加入防火墙2.4、查看防火墙中开放的端口2.5、使用新ssh端口连接服务器 3、总结 1、概述 大家好&#xff0c;我是欧阳方超&#xff0c;可以关注我的公众号“欧阳方超…

Vue解决首屏加载缓慢的首屏优化秒开(亲测有效)

一.开启gzip打包 在vue.config.js文件中 &#xff08;1&#xff09;.使用chainWebpack配置的方式 chainWebpack(config){ config.module.rule(vue).use(vue-loader).loader(vue-loader).tap(options > {options.compilerOptions.preserveWhitespace truereturn options…