代码随想录算法训练营第十天 | 二叉树系列1

news2024/7/4 5:22:18

二叉树系列1

  • 二叉树理论基础
    • 注意点小记
      • 二叉树的种类
      • 二叉树的存储方式
      • 二叉树的遍历
    • 要熟悉自己所用编程语言常用的数据容器的底层实现
    • 一定要会自己实现所用数据结构的定义
  • 二叉树的递归遍历
    • 递归三部曲
    • 前中后序递归遍历
    • 前序遍历--我的代码
    • 前序遍历--代码随想录的代码
    • 中序遍历--我的代码
    • 后序遍历--我的代码
  • 二叉树的非递归遍历--迭代法
    • 注意点记录
    • 代码随想录强调
    • 一刷逻辑还没有理清,对迭代法的思路没有掌握
    • 代码随想录的代码
    • 我的代码(当天晚上自己写)
  • 二叉树的非递归遍历--迭代法统一编写方式
    • 重点
    • 代码随想录的代码
    • 我的代码(当日晚上自己写)
  • 二叉树的层序遍历
    • 重点
    • 代码随想录的代码
    • 我的代码(当日晚上自己写)
  • 用层序遍历打10个!
    • 注:后面10题,均使用迭代法来进行层序遍历,递归版本的二刷再写。
    • 102 就是层序遍历
    • 107 二叉树的层序遍历 II
      • 我的代码
    • 199 二叉树的右视图
      • 我的代码
    • 637 二叉树的层平均值
    • 429 N 叉树的层序遍历
      • 我的代码
    • 515 在每个树行中找最大值
      • 我的代码
    • 116 填充每个节点的下一个右侧节点指针
      • 我的代码
      • 代码随想录的代码
    • 117 填充每个节点的下一个右侧节点指针 II
    • 104 二叉树的最大深度
    • 559 n叉树的最大深度
    • 111 二叉树的最小深度
      • 我的代码
  • 226 翻转二叉树
    • 注意
    • 代码随想录的代码
    • 我的代码(当日晚上自己写,不是独立完成,二刷要重视)
  • 二叉树第一周小结

二叉树理论基础

先放上代码随想录的文章链接。

二叉树理论基础

注意点小记

二叉树的种类

1:完全二叉树底层不一定是满的,但是从左到右必须是连续的。
2:二叉搜索树:二叉搜索树的时间复杂度是O(logn),比如插入、查询。二叉搜索树对树的结构没有要求,对树的节点的顺序有一定要求。
3:满二叉树:满的
4、平衡二叉搜索树:左子树和右子树高度的绝对值的差不能大于1。

二叉树的存储方式

1:顺序存储,用一个数组去存储下标,如果父节点的数组下标是 i ,那么左孩子是 2i+1 , 右孩子是 2i+2 。在对二叉树进行顺序存储时,要先将二叉树扩充为完全二叉树,这样才满足左右孩子的计算方式。

2:顺序存储的方式很少用,一般均用链式存储,二叉树可以理解为就是一种链表,传入一个二叉树,就是传入一个链表。

二叉树的遍历

1:前序遍历、中序遍历、后序遍历:本质上均为深度优先搜索。先往深走,遇到叶子节点返回。DFS的实现大多用递归实现,而前中后序遍历,也均有两种实现方式(递归法、迭代法),用递归可以实现的,用栈也可以模拟递归的过程。

2:层序遍历:本质为广度优先搜索。实现上就是迭代法,用一个队列来实现,BFS的实现也是队列,先进先出的特性满足一层一层遍历的需求。

3:前中后序遍历,其实指的就是中间节点的遍历顺序。前–中左右,中:左中右,后:左右中。

要熟悉自己所用编程语言常用的数据容器的底层实现

下面是从网上找的一篇博客,讲的很详细。

使用Python实现常见的数据结构之原理讲解

一定要会自己实现所用数据结构的定义

这里是要会定义:二叉树的节点。(实现方式其实就是链表)

class TreeNode:
	def __init__(self,val,left=None,right=None):
		self.val = val
		self.left = left
		self.right = right

二叉树的递归遍历

递归遍历,学习如何写递归。递归三部曲将贯穿整个二叉树章节。

递归三部曲

1、确定递归函数的参数和返回值。(不必一次性就确定好,需要什么定义什么,二叉树章节一般为根节点+数组用于存储结果)
2、确定终止条件。
3、确定单层递归的逻辑。

前中后序递归遍历

放数组的操作即为:中
进左节点:左
进右节点:右
按照这个定义以及前中后序的逻辑,按顺序编写即可。

前序遍历–我的代码

对比之后还是觉得应该学习代码随想录的编写方式,不能因为函数中没有传入储存结果的变量,就去重新编写一个函数,还是对递归理解的不到位。

class TreeNode:
    def __init__(self,val,left=None,right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
        self.digui(root,res)
        return res

    def digui(self,root: Optional[TreeNode],res):
        if root == None :
            return
        res.append(root.val)
        self.digui(root.left,res)
        self.digui(root.right,res)

前序遍历–代码随想录的代码

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        if not root:
            return []

        left = self.preorderTraversal(root.left)
        right = self.preorderTraversal(root.right)

        return  [root.val] + left +  right

中序遍历–我的代码

接下来的遍历,不再额外编写一个带存储结果变量的递归函数。

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []
        left = self.inorderTraversal(root.left)
        right = self.inorderTraversal(root.right)

        return left + [root.val] + right

后序遍历–我的代码

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []

        left = self.postorderTraversal(root.left)
        right = self.postorderTraversal(root.right)

        return left + right + [root.val]

二叉树的非递归遍历–迭代法

比较有难度!要好好理解。

代码随想录的讲解文章链接:
二叉树的迭代法遍历

递归的实现就是:每一次递归调用都会把函数的局部变量、参数值和返回地址等压入调用栈中,然后递归返回的时候,从栈顶弹出上一次递归的各项参数,所以这就是递归为什么可以返回上一层位置的原因。

注意点记录

前序–中左右:入栈顺序为–中右左,因为栈是先入后出。

中序遍历和前序遍历,是完全不一样的,不能用相同的逻辑!

中序遍历:用一个指针来遍历节点,用栈来记录遍历过的元素。
在这里插入图片描述
后序遍历:可以通过更改前序代码来实现。
在这里插入图片描述

代码随想录强调

在用迭代法实现遍历的过程中,要明确两个概念:遍历节点和处理节点,因为前序遍历时,二者一致,才可以较为简洁地写出代码。

仔细思考前序遍历的顺序–中左右,以及前序遍历的迭代法的迭代顺序(这里要好好思考一下,中间节点处理之后,push左右进去,但是下一层循环只处理一个,也就是说,在左右均可遍历的情况下,push两个pop一个),可以发现完全一致!

一刷逻辑还没有理清,对迭代法的思路没有掌握

一刷没有自己写的代码。

代码随想录的代码

前序遍历:

class TreeNode:
    def __init__(self,val,left=None,right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        res = []
       
        if root == None:
           return []
        stack  = [root]

        while stack != [] :
            node = stack.pop()
           
            res.append(node.val)

            if node.right :
                stack.append(node.right)
            if node.left :
                stack.append(node.left)
        return res

后序遍历:

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []
        res = []
        stack = [root]
        while stack != [] :
            node = stack.pop()
            res.append(node.val)

            if node.left :
                stack.append(node.left)

            if node.right :
                stack.append(node.right)
        res.reverse()
        return res

中序遍历:

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None:
            return []
        res = []
        stack = []
        cur = root
        while cur or stack :
            if cur :
                stack.append(cur)
                cur = cur.left
            else :
                cur = stack.pop()

                res.append(cur.val)

                cur = cur.right
        return res

我的代码(当天晚上自己写)

前序遍历:

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []
        stack = [root]
        res = []
        while stack :
            node = stack.pop()
            res.append(node.val)

            # 这里注意,因为所用的stack为先进后出,所以先序遍历:中左右
            # 是先加入右子树
            if node.right :
                stack.append(node.right)
            if node.left :
                stack.append(node.left)
        return res

后序遍历:

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []
        res = []
        stack = [root]
        while stack != [] :
            node = stack.pop()
            res.append(node.val)

            if node.left :
                stack.append(node.left)

            if node.right :
                stack.append(node.right)
        res.reverse()
        return res

中序遍历:(没写出来,错误代码)

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []

        stack = []
        res = []

        cur = root

        while cur or stack != [] :
            
            if cur == None :
                node = stack.pop()
                res.append(node.val)
                cur = node

            else :
                stack.append(cur.left)
                cur = cur.left

二叉树的非递归遍历–迭代法统一编写方式

有困难,一刷不会。

重点

重点在于明确,只对中节点操作,即放入res中。

代码随想录的代码

前序遍历:

class Solution:
    def preorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        st= []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node != None:
                if node.right: #右
                    st.append(node.right)
                if node.left: #左
                    st.append(node.left)
                st.append(node) #中
                st.append(None)
            else:
                node = st.pop()
                result.append(node.val)
        return result

中序遍历:

class Solution:
    def inorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node != None:
                if node.right: #添加右节点(空节点不入栈)
                    st.append(node.right)
                
                st.append(node) #添加中节点
                st.append(None) #中节点访问过,但是还没有处理,加入空节点做为标记。
                
                if node.left: #添加左节点(空节点不入栈)
                    st.append(node.left)
            else: #只有遇到空节点的时候,才将下一个节点放进结果集
                node = st.pop() #重新取出栈中元素
                result.append(node.val) #加入到结果集
        return result

后序遍历:

class Solution:
    def postorderTraversal(self, root: TreeNode) -> List[int]:
        result = []
        st = []
        if root:
            st.append(root)
        while st:
            node = st.pop()
            if node != None:
                st.append(node) #中
                st.append(None)
                
                if node.right: #右
                    st.append(node.right)
                if node.left: #左
                    st.append(node.left)
            else:
                node = st.pop()
                result.append(node.val)
        return result

我的代码(当日晚上自己写)

前序遍历:注意处理逻辑,前序为中左右,换成栈的先入后出逻辑为,右左中。

class Solution:
    def preorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []

        res = []
        stack = [root]

        while stack :
            node = stack.pop()
            
            if node == None:
                temp = stack.pop()
                res.append(temp.val)
            else :
                if node.right :
                    stack.append(node.right)
                if node.left :
                    stack.append(node.left)
                stack.append(node)
                stack.append(None)
        return res

中序遍历:
左中右,换算成栈为:右中左

class Solution:
    def inorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []

        stack = [root]
        res = []

        while stack :
            node = stack.pop()
            if node == None :
                res.append(stack.pop().val)

            else:
                if node.right :
                    stack.append(node.right)
                stack.append(node)
                stack.append(None)
                if node.left :
                    stack.append(node.left)
        return res

后序遍历:
左右中,换算成栈为:中右左

class Solution:
    def postorderTraversal(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []
        stack = [root]
        res = []

        while stack :
            node = stack.pop()
            if node == None :
                res.append(stack.pop().val)
            else :
                stack.append(node)
                stack.append(None)
                if node.right :
                    stack.append(node.right)

                if node.left :
                    stack.append(node.left)

        return res

二叉树的层序遍历

没思路,直接对代码随想录的文章进行学习。需要明确:层序遍历用队列来实现。

重点

迭代法的理解较为直观。递归方法的理解:按照递归三部曲,确定处理逻辑即可。

代码随想录的代码

迭代法:

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if not root:
            return []
        queue = collections.deque([root])
        result = []
        while queue:
            level = []
            for _ in range(len(queue)):
                cur = queue.popleft()
                level.append(cur.val)
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
            result.append(level)
        return result

递归法:

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        levels = []
        self.helper(root, 0, levels)
        return levels
    
    def helper(self, node, level, levels):
        if not node:
            return
        if len(levels) == level:
            levels.append([])
        levels[level].append(node.val)
        self.helper(node.left, level + 1, levels)
        self.helper(node.right, level + 1, levels)

我的代码(当日晚上自己写)

迭代法:

from collections import deque
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root == None :
            return []
        result = []
        
        dq = deque()
        dq.append(root)

        while dq :
            size = len(dq)
            res = []
            for i in range(size):
                node = dq.popleft()
                res.append(node.val)
                if node.left:
                    dq.append(node.left)
                if node.right :
                    dq.append(node.right)
            result.append(res)

        return result

递归法:(第一遍错误代码)

如果加嵌套列表以及递归逻辑均错误。

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root == None :
            return []
        res = []
        self.digui(root,0,res)
        return res

    def digui(self,root,depth,res):
        if root == None:
            return 
        res[depth].append(root.val)
        depth += 1
        self.digui(root.left,depth,res)
        depth -= 1
        self.digui(root.right,depth,res)
        depth -= 1

递归法:(改正后代码)
每次记得append空列表,depth不需要回退减一,因为depth是参数,回退之后自然就是正确的数值。

class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root == None :
            return []
        res = []
        self.digui(root,0,res)
        return res

    def digui(self,root,depth,res):
        if root == None:
            return 
        if len(res)==depth:
            res.append([])
        res[depth].append(root.val)
        depth += 1
        self.digui(root.left,depth,res)
        self.digui(root.right,depth,res)

用层序遍历打10个!

注:后面10题,均使用迭代法来进行层序遍历,递归版本的二刷再写。

102 就是层序遍历

107 二叉树的层序遍历 II

先获取层序遍历,后翻转。

我的代码

from collections import deque
class Solution:
    def levelOrderBottom(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root == None :
            return []
        dq = deque()
        dq.append(root)
        res = []
        while dq :
            size = len(dq)
            level = []
            for i in range(size):
                node = dq.popleft()
                level.append(node.val)
                if node.left :
                    dq.append(node.left)
                if node.right:
                    dq.append(node.right)
            res.append(level)

        n = len(res)
        left = 0
        right = n-1
        while left < right :
            res[left],res[right] = res[right],res[left]
            left += 1
            right -= 1
        return res


199 二叉树的右视图

难点在于,要想到用层序遍历,一直向right遍历是不行的,可能存在左子树比右子树深的情况。

我的代码

from collections import deque
class Solution:
    def rightSideView(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []
        res = []
        dq = deque()
        dq.append(root)
        while dq :
            size = len(dq)
            level = []
            for i in range(size):
                node = dq.popleft()
                '''
                这里不用每个都append进level里,甚至level都不需要声明
                只需要 if i == size-1 , 直接append到res里就好了
                '''
                level.append(node.val)
                if node.left :
                    dq.append(node.left)
                if node.right:
                    dq.append(node.right)
            res.append(level[-1])
        return res

637 二叉树的层平均值

过。

429 N 叉树的层序遍历

我的代码

from collections import deque
class Solution:
    def levelOrder(self, root: Optional[TreeNode]) -> List[List[int]]:
        if root == None :
            return []
        result = []
        
        dq = deque()
        dq.append(root)

        while dq :
            size = len(dq)
            res = []
            for i in range(size):
                node = dq.popleft()
                res.append(node.val)

                n = len(node.children)
                for j in range(n):
                    dq.append(node.children[j])
            result.append(res)
    

        return result

515 在每个树行中找最大值

我的代码

class Solution:
    def largestValues(self, root: Optional[TreeNode]) -> List[int]:
        if root == None :
            return []
        result = []
        
        dq = deque()
        dq.append(root)

        while dq :
            size = len(dq)
            maximum = -inf
            for i in range(size):
                node = dq.popleft()
                if node.val > maximum :
                    maximum = node.val
                
                if node.left:
                    dq.append(node.left)
                if node.right :
                    dq.append(node.right)
            result.append(maximum)

        return result

116 填充每个节点的下一个右侧节点指针

我的代码

from collections import deque
class Solution:
    def connect(self, root: 'Optional[Node]') -> 'Optional[Node]':
        if root == None :
            return None
           
        dq = deque()
        dq.append(root)

        while dq :
            size = len(dq)
            
            for i in range(size):
                
                node = dq.popleft()
                if i < size-1:
                    rnext = dq[0]
                    node.next = rnext

                if node.left:
                    dq.append(node.left)
                if node.right :
                    dq.append(node.right)
           
        return root

代码随想录的代码

看上去更好一些,维护一个prev,不需要每次循环去调用 dq[0]

class Solution:
    def connect(self, root: 'Node') -> 'Node':
        if not root:
            return root
        
        queue = collections.deque([root])
        
        while queue:
            level_size = len(queue)
            prev = None
            
            for i in range(level_size):
                node = queue.popleft()
                
                if prev:
                    prev.next = node
                
                prev = node
                
                if node.left:
                    queue.append(node.left)
                
                if node.right:
                    queue.append(node.right)
        
        return root

117 填充每个节点的下一个右侧节点指针 II

和116没有任何区别

104 二叉树的最大深度

层序遍历计数,过。

559 n叉树的最大深度

层序遍历计数,过。

111 二叉树的最小深度

需要注意的是,只有当左右孩子都为空的时候,才说明遍历的最低点了。如果其中一个孩子为空则不是最低点。

我的代码

from collections import deque
class Solution:
    def minDepth(self, root: Optional[TreeNode]) -> int:
        if root == None :
            return 0
        
        dq = deque()
        dq.append(root)
        depth = 0
        min_dep = inf

        while dq :
            size = len(dq)
            depth += 1
            for i in range(size):
                node = dq.popleft()
                if node.left == None and node.right == None :
                    if depth < min_dep  :
                        min_dep = depth
                else :
                    if node.left:
                        dq.append(node.left)
                    if node.right :
                        dq.append(node.right)
            

        return min_dep

226 翻转二叉树

一刷没思路,直接学习了代码随想录的讲解。

注意

注意只要把每一个节点的左右孩子翻转一下,就可以达到整体翻转的效果

这道题目使用前序遍历和后序遍历都可以,唯独中序遍历不方便,因为中序遍历会把某些节点的左右孩子翻转了两次!

这里自己画图试一试就可以理解,一刷通过画图已理解,如果硬要套中序遍历,是翻转两次 left 。

那么层序遍历可以不可以呢?依然可以的!只要把每一个节点的左右孩子翻转一下的遍历方式都是可以的!

代码随想录的代码

在这里插入图片描述
递归(前序遍历):

class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return None
        root.left, root.right = root.right, root.left
        self.invertTree(root.left)
        self.invertTree(root.right)
        return root

递归(后序遍历):
略,二刷时编写。

递归法(中序遍历,两次 left):

class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return None
        self.invertTree(root.left)
        root.left, root.right = root.right, root.left
        self.invertTree(root.left)
        return root

迭代法(DFS,前序遍历):

class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if not root:
            return None      
        stack = [root]        
        while stack:
            node = stack.pop()   
            node.left, node.right = node.right, node.left                   
            if node.left:
                stack.append(node.left)
            if node.right:
                stack.append(node.right)  
        return root

迭代法(DFS,后序遍历):
略,二刷时编写。

迭代法(DFS,中序遍历,两次 left):
略,二刷时编写。

迭代法(DFS,统一写法中序遍历,不需要两次 left):
无,注意交换处理逻辑的位置。

迭代法(BFS,层次遍历):

class Solution:
    def invertTree(self, root: TreeNode) -> TreeNode:
        if not root: 
            return None

        queue = collections.deque([root])    
        while queue:
            for i in range(len(queue)):
                node = queue.popleft()
                node.left, node.right = node.right, node.left
                if node.left: queue.append(node.left)
                if node.right: queue.append(node.right)
        return root   

我的代码(当日晚上自己写,不是独立完成,二刷要重视)

递归(前序遍历):

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root == None:
            return None
        root.left , root.right = root.right , root.left
        self.invertTree(root.left)
        self.invertTree(root.right)
        return root

递归法(中序遍历,两次 left):

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root == None:
            return None
        self.invertTree(root.left)
        root.left, root.right = root.right, root.left
        self.invertTree(root.left)

        return root

迭代法(DFS,前序遍历):

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root == None :
           return None
        stack = [root]
        while stack:
            node = stack.pop()
            node.left , node.right = node.right , node.left
            if node.right :
                stack.append(node.right)
            if node.left:
                stack.append(node.left)
        return root

迭代法(DFS,后序遍历):
略,二刷时编写。

迭代法(DFS,中序遍历,两次 left):
略,二刷时编写。

迭代法(DFS,统一写法中序遍历,不需要两次 left):
注意交换处理逻辑的位置。

class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root == None :
            return None
        stack = [root]
        
        while stack :
            node = stack.pop()
            if node :
                if node.right:
                    stack.append(node.right)
                stack.append(node)
                stack.append(None)
                
                if node.left:
                    stack.append(node.left)
                
            else :
                node = stack.pop()
                # 注意,交换处理逻辑的位置
                node.left , node.right = node.right , node.left

        return root

迭代法(BFS,层次遍历):

from collections import deque
class Solution:
    def invertTree(self, root: Optional[TreeNode]) -> Optional[TreeNode]:
        if root == None :
            return None
        dq = deque()
        dq.append(root)
        
        while dq :
            size = len(dq)
            
            for i in range(size):
                node = dq.popleft()
                # 注意处理逻辑的位置
                node.left, node.right = node.right, node.left
                if node.left :
                    dq.append(node.left)
                if node.right:
                    dq.append(node.right)
      
        return root

二叉树第一周小结

代码随想录总结的很好很到位,直接上链接。

二叉树第一周小结

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

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

相关文章

【解决】Pyinstaller打包报错IndexError: tuple index out of range

问题 这个问题主要是在Python3.7以上的版本中遇到&#xff0c;用pyinstaller打包的时候发现报错 /usr/local/lib/python3.10/dis.py argval const_list[const_index], IndexError: tuple index out of range解决方案 vim 进入报错的文件&#xff0c;/usr/local/lib/python…

Css 基础:选择器,三大特性

1.emmet的 快速格式化代码 配置 "editor.formatOnType": true, "editor.formatOnSave": true 2.基础选择器 3.复合选择器 4.单行文本垂直居中原理 5.css背景 6.CSS三大特性 层叠性&#xff1a;相同选择器设置相同样式&#xff0c;发生在样式冲突时&#xf…

VUE:el-button里面的倒计时显示,验证码发送后两分钟倒计时

验证码倒计时显示 框架需求样式图代码template部分script部分style部分部分内容解读 框架 UI&#xff1a;elementUI 前端&#xff1a;vue 需求 发送验证码后&#xff0c;2分钟内不可以在发送&#xff0c;button置灰&#xff0c;120s后可以点击重新发送验证码 样式图 代码 …

【算法设计与分析】拉丁矩阵问题——对于给定的m和n,计算出不同的宝石排列方案数。

问题描述 现有n种不同形状的宝石&#xff0c;每种宝石有足够多颗。欲将这些宝石排列成m行n列的一个矩阵&#xff0c;m≤n&#xff0c;使矩阵中每行和每列的宝石都没有相同的形状。试设计一个算法&#xff0c;计算出对于给定的m和n&#xff0c;有多少种不同的宝石排列方案。 数…

Java 基础进阶篇(三):权限修饰符、final 关键字与枚举

文章目录 一、权限修饰符二、final 关键字2.1 final 作用2.2 final 修饰变量举例2.3 常量三、枚举3.1 枚举的格式3.2 枚举的特征3.3 枚举的应用 一、权限修饰符 权限修饰符 用于约束成员变量、构造器、方法等的访问范围。 权限修饰符&#xff1a; 有四种作用范围由小到大 (priv…

Unity 如何导入二进制Spine文件

Unity 如何导入二进制Spine文件 前言步骤1.修改拓展名2.修改参数3.导出文件4.导入文件5.修改材质球属性6.生成动画 参考 前言 总是忘记Spine导出二进制到Unity的设置&#xff0c;记录一下。 步骤 1.修改拓展名 纹理打包器也修改一下拓展名&#xff08;日常操作&#xff09;…

word@制表位和列数据对齐@填空下划线制作

文章目录 refs制表位(tab stop)制表位类型 制作对其的下划线填空表单&#x1f47a;利用前导符代替下划线制作待填空下划线 制表位对其列数据模拟简单表格测试数据设置引线使用标尺设置 FAQ refs Insert or add tab stops - Microsoft SupportUsing the ruler in Word - Micros…

GaN HEMT主要性能指标有哪些?宽禁带材料电性能测试方案

GaN HEMT器件性能的评估&#xff0c;一般包含静态参数测试&#xff08;I-V测试&#xff09;、频率特性&#xff08;小信号S参数测试&#xff09;、功率特性&#xff08;Load-Pull测试&#xff09;。静态参数&#xff0c;也被称作直流参数&#xff0c;是用来评估半导体器件性能…

JVM理论(一)-基础概念

JVM概述 JVM就是二进制字节码的运行环境,负责装载字节码到其内存,解释/编译为对应平台上的机器指令执行,每条java指令在java虚拟机规范中都有详细定义,包括如何取、处理操作数等;JVM特点如下 一次编译,到处运行&#xff08;各CPU的架构不同的情况下JVM为了实现跨平台,字节码指…

fastadmin使用PHPexcel上传文件处理兼容问题 (已解决)

介绍 fastadmin&#xff1a;支持使用7.0以上版本的PHP PHPexcel&#xff1a;不支持使用7.0以上的PHP版本 2.下载地址 https://codeload.github.com/PHPOffice/PHPExcel/zip/1.8 3&#xff1a;解决兼容 将文件导入到vendor下面&#xff0c;创建一个函数来使用这个文件&…

5.8.10 TCP协议

5.8.10 TCP协议 我们通过一个实例来看一下TCP协议 如图 图中是六个IP数据报的前40个字节的内容&#xff0c;使用的是16进制数表示的&#xff0c;该数据报的背景如下图 主机H通过快速以太网连接Internet&#xff0c;主机H的IP地址是192.168.1.100&#xff0c;服务器S的IP地址是…

高迸发 架构设计方案

前言 ​​在实际生活业务场景开发中&#xff0c;在我们的网站知名度越来越大的时候&#xff0c;随之而来的就是业务体量越来越大&#xff0c;用户群体越来越大&#xff0c;随之而来的技术要求也越来越高&#xff0c;其中核心点对网站的稳定性要求是硬性的。如果一个系统都无法…

新装idea的一些常用设置

新装idea的一些常用设置 新安装的idea常用配置 1、提示内容忽略大小写 File -> Settings -> Editor -> General -> Code Completion -> Match case 2、修改字体大小 File -> Settings -> Editor -> Font -> Size 3、取消启动时自动打开最后开…

阿里云国际站:阿里云计算服务指的是什么?

标题&#xff1a;阿里云计算服务指的是什么&#xff1f; 一、阿里云计算服务的定义   阿里云计算服务&#xff0c;是阿里巴巴集团旗下的云服务平台&#xff0c;提供了从云服务器、云数据库到大数据处理等丰富的云计算服务。它通过构建一种共享的计算资源池&#xff0c;使得用…

《SpringBoot》第05章 配置文件解析

前言 SpringBoot中的application.properties(或application.yaml)文件都是再熟悉不过的了。它是应用的配置文件&#xff0c;我们可以把需要的一些配置信息都写在这个文件里面&#xff0c;需要的时候&#xff0c;我们可以通过Value注解来直接获取即可&#xff0c;那这个文件是什…

deepstream指北——python接口的使用

目录 一、机器配置二、环境配置三、运行实例 一、机器配置 电脑&#xff1a;台式机系统&#xff1a;Ubuntu 20.04.5显卡&#xff1a;GTX 1070&#xff0c;8G显存软件版本&#xff1a;deepstream&#xff1a;6.1.1显卡驱动版本&#xff1a;515.76CUDA版本&#xff1a;11.7.1cud…

基于PyQt5的桌面图像调试仿真平台开发(10)色彩矩阵

系列文章目录 基于PyQt5的桌面图像调试仿真平台开发(1)环境搭建 基于PyQt5的桌面图像调试仿真平台开发(2)UI设计和控件绑定 基于PyQt5的桌面图像调试仿真平台开发(3)黑电平处理 基于PyQt5的桌面图像调试仿真平台开发(4)白平衡处理 基于PyQt5的桌面图像调试仿真平台开发(5)…

当赛博朋克碰上小鸡舞 segment anything

Segment Anything能给我们做什么 前言内容具体实现成果 前言 最近&#xff0c;大模型的热度确实是非常非常的高&#xff0c;从chatgpt到segment anything&#xff0c;这些东西整的我这刚入门的小白确实有点懵逼。最近实在是不知道干啥&#xff0c; 想想能不能用大模型整点花活…

Spring后置处理器BeanFactoryPostProcessor与BeanPostProcessor源码解析

文章目录 一、简介1、BeanFactoryPostProcessor2、BeanPostProcessor 二、BeanFactoryPostProcessor 源码解析1、BeanDefinitionRegistryPostProcessor 接口实现类的处理流程2、BeanFactoryPostProcessor 接口实现类的处理流程3、总结 三、BeanPostProcessor 源码解析 一、简介…

uniapp 之 多端实现图片压缩(含H5实现)

compressImage 说明 文档平台差异说明已标出&#xff1a;官网提供的api uni.compressImage除了H5平台&#xff0c;其余平台都支持&#xff0c;所以我们利用条件编译&#xff0c;然后单独处理一下H5的图片压缩即可。 utils.js 里面封装一下该方法&#xff0c;方便调用 /*** 图…