leetcode2021年度刷题分类型总结(五)二叉树 (python)

常用方法总结:

  1. 递归遍历:(前序中序后序层序)
    层序遍历:层序遍历一个二叉树。就是从左到右一层一层的去遍历二叉树。需要借用一个辅助数据结构即队列来实现,队列先进先出,符合一层一层遍历的逻辑
  2. 迭代遍历:用栈实现二叉树的前后中序遍历

例一:104. 二叉树的最大深度(递归法、层序遍历法、前序遍历法)

给定一个二叉树,找出其最大深度。

二叉树的深度为根节点到最远叶子节点的最长路径上的节点数。

说明: 叶子节点是指没有子节点的节点。

示例:
给定二叉树 [3,9,20,null,null,15,7],

在这里插入图片描述
分别用递归法、层序遍历法、前序遍历法解答如下:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        #递归法 
        #1.确定递归函数的参数和返回值(root和depth) 2.确定终止条件:如果为空节点的话,就返回0,表示高度为0。
        #3.确定单层递归的逻辑:先求它的左子树的深度,再求的右子树的深度,最后取左右深度最大的数值 再+1 (加1是因为算上当前中间节点)就是目前节点为根节点的树的深度。

        depth=0
        def depth(root,d):
            if not root:
                return 0
            ldepth=depth(root.left,depth)
            rdepth=depth(root.right,depth)
            d=1+max(ldepth,rdepth)
            return d

        return depth(root,depth)
        #层序遍历法
        #层序遍历,每到一层加1
        if not root:
            return 0

        from collections import deque
        queue=deque([root])
        depth=0

        while queue:
            size=len(queue)
            depth+=1
            for _ in range(size):
                cur=queue.popleft()
                if cur.left:
                    queue.append(cur.left)
                if cur.right:
                    queue.append(cur.right)
                    
        return depth

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def __init__(self):
        root=TreeNode(None)
        self.result=0
    def getdepth(self,root,depth):
                self.result=depth if depth>self.result else self.result #中
                # print(result)
                if root.left==None and root.right==None:
                    return 
                if root.left:
                    self.getdepth(root.left,depth+1) #左

                if root.right:
                    self.getdepth(root.right,depth+1) #右

                return
    def maxDepth(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        ##前序遍历
        self.result=0

        if not root:
            return 0
        self.getdepth(root,1)
        return self.result

例二:559. N 叉树的最大深度(递归法、层序遍历)

给定一个 N 叉树,找到其最大深度。

最大深度是指从根节点到最远叶子节点的最长路径上的节点总数。

N 叉树输入按层序遍历序列化表示,每组子节点由空值分隔(请参见示例)。
在这里插入图片描述

"""
# Definition for a Node.
class Node(object):
    def __init__(self, val=None, children=None):
        self.val = val
        self.children = children
"""

class Solution(object):
    def maxDepth(self, root):
        """
        :type root: Node
        :rtype: int
        """
        ## 递归法
        if not root:
            return 0
        depth=0
        for i in range(len(root.children)):
            depth=max(depth,self.maxDepth(root.children[i])) #最大深度等于各个子树中最大的深度 最后加1

        return depth+1 #回溯时期执行加和操作

        
        ##层序遍历
        if not root:
            return 0
        
        from collections import deque
        queue=deque([root])

        result=0


        while queue:
            size=len(queue)
            result+=1
            for i in range(size):
                cur=queue.popleft()
                # print(cur)
                for i in range(len(cur.children)):
                    queue.append(cur.children[i])
             
        return result

例三:144. 二叉树的前序遍历(递归遍历、)

144. 二叉树的前序遍历

前序遍历:中左右,递归调用traversal()函数。
过程简述:每次调用traversal()函数时,先判断是否遍历到的节点是否空了,如果是,返回到上一次traversal()的调用。traversal()函数先把root.val收集到res中,之后先对root的左子节点做同样操作(root.left作为新的root,收集到res中,再将root.left.left作为新的root,如果其存在的话),最后对右子节点做同样操作(从最左侧底部的右子节点开始)

class Solution(object):
    def preorderTraversal(self, root):
        """
        :type root: TreeNode
        :rtype: List[int]
        """
        
        def traversal(root):
            if root==None:
                return
            res.append(root.val) #中
            traversal(root.left) #左
            traversal(root.right) #右
            
        res=[]
        traversal(root,res)
        return res

例四:剑指 Offer 07. 重建二叉树

输入某二叉树的前序遍历和中序遍历的结果,请构建该二叉树并返回其根节点。

假设输入的前序遍历和中序遍历的结果中都不含重复的数字。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, x):
#         self.val = x
#         self.left = None
#         self.right = None

class Solution(object):
    def buildTree(self, preorder, inorder):
        """
        :type preorder: List[int]
        :type inorder: List[int]
        :rtype: TreeNode
        """
        def myBuildTree(preorder_left, preorder_right, inorder_left, inorder_right): #用指针在preorder和inorder数组中定位
            if preorder_left > preorder_right:
                return None
            # 前序遍历中的第一个节点就是根节点
            preorder_root = preorder_left
            # 在中序遍历中定位根节点
            inorder_root = index[preorder[preorder_root]] #关键信息:输入的前序遍历和中序遍历的结果中都不含重复的数字
            # 先把根节点建立出来
            root = TreeNode(preorder[preorder_root])
            # 得到左子树中的节点数目
            size_left_subtree = inorder_root - inorder_left
            # 递归地构造左子树,并连接到根节点
            # 先序遍历中「从 左边界+1 开始的 size_left_subtree」个元素就对应了中序遍历中「从 左边界 开始到 根节点定位-1」的元素
            root.left = myBuildTree(preorder_left + 1, preorder_left + size_left_subtree, inorder_left, inorder_root - 1) #root.left是建立出来的一个子树

            # 递归地构造右子树,并连接到根节点
            # 先序遍历中「从 左边界+1+左子树节点数目 开始到 右边界」的元素就对应了中序遍历中「从 根节点定位+1 到 右边界」的元素
            root.right = myBuildTree(preorder_left + size_left_subtree + 1, preorder_right, inorder_root + 1, inorder_right)
            return root
        
        n = len(preorder)
        # 构造哈希映射,帮助我们快速定位根节点
        index = {element: i for i, element in enumerate(inorder)} #key:value
        return myBuildTree(0, n - 1, 0, n - 1) 

例五:101. 对称二叉树

给你一个二叉树的根节点 root , 检查它是否轴对称。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def isSymmetric(self, root):
        """
        :type root: TreeNode
        :rtype: bool
        """
        # if not root:
        #     return True
        # def  symmetric(rootl,rootr):
        #     if not rootl and not rootr:
        #         return True
        #     if not rootl or not rootr:
        #         return False
        #     if  rootl.val!=rootr.val:
        #         return False

        #     outside=symmetric(rootl.left,rootr.right)
        #     inside=symmetric(rootr.left,rootl.right)

        #     return  outside and inside

        # return symmetric(root.left,root.right)

        ##使用栈
        from collections import deque
        if not root:
            return True
        queue = collections.deque()
        queue.append(root.left) #将左子树头结点加入队列
        queue.append(root.right) #将右子树头结点加入队列
        while queue: #接下来就要判断这这两个树是否相互翻转
            leftNode = queue.popleft()
            rightNode = queue.popleft()
            if not leftNode and not rightNode: #左节点为空、右节点为空,此时说明是对称的
                continue
            
            #左右一个节点不为空,或者都不为空但数值不相同,返回false
            if not leftNode or not rightNode or leftNode.val != rightNode.val:
                return False
            queue.append(leftNode.left) #加入左节点左孩子
            queue.append(rightNode.right) #加入右节点右孩子
            queue.append(leftNode.right) #加入左节点右孩子
            queue.append(rightNode.left) #加入右节点左孩子
        return True

例六:257. 二叉树的所有路径

给你一个二叉树的根节点 root ,按 任意顺序 ,返回所有从根节点到叶子节点的路径。

叶子节点 是指没有子节点的节点。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def binaryTreePaths(self, root):
        """
        :type root: TreeNode
        :rtype: List[str]
        """
        ##递归法:前序遍历 
        path=''
        result=[]
        if not root:
            return result

        def dfs(root,path,result):
            # if not root:
            #     return 
            path+=str(root.val)
            if not root.left and not root.right:
                result.append(path)
                return 

            if root.left:
                dfs(root.left,path+"->",result)
            if root.right:
                dfs(root.right,path+"->",result)

        dfs(root,path,result)

        return result
        
        ##迭代法
        # 题目中节点数至少为1
        stack, path_st, result = deque([root]), deque(), []
        path_st.append(str(root.val))

        while stack:
            cur = stack.pop()
            path = path_st.pop()
            # 如果当前节点为叶子节点,添加路径到结果中
            if not (cur.left or cur.right):
                result.append(path)
            if cur.right:
                stack.append(cur.right)
                path_st.append(path + '->' + str(cur.right.val))
            if cur.left:
                stack.append(cur.left)
                path_st.append(path + '->' + str(cur.left.val))
        ##递归的底层实现就是栈,这里要注意由于是前序遍历(深度、从根到叶),所以要先压入右节点再压入左节点
        return result

分析:递归+回溯

这题的特点是递归的解法中隐藏了回溯的逻辑
貌似表面没有看到回溯的逻辑,其实不然,回溯就隐藏在traversal(cur->left, path + “->”, result);中的 path + “->”。 每次函数调用完,path依然是没有加上"->" 的,这就是回溯了。
当然在函数定义的时候void traversal(TreeNode* cur, string path, vector& result) ,定义的是string path,每次都是复制赋值,不用使用引用,否则就无法做到回溯的效果。它的写法相当于:

if (cur->left) {
    path += "->";
    traversal(cur->left, path, result); // 左
    path.pop_back(); // 回溯,抛掉val
    path.pop_back(); // 回溯,抛掉->
}
if (cur->right) {
    path += "->";
    traversal(cur->right, path, result); // 右
    path.pop_back(); // 回溯(非必要)
    path.pop_back(); 
}

例七:404. 左叶子之和

给定二叉树的根节点 root ,返回所有左叶子之和。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def sumOfLeftLeaves(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        #本题我们要通过节点的父节点判断本节点的属性。
        #判断当前节点是不是左叶子是无法判断的,必须要通过节点的父节点来判断其左孩子是不是左叶子。

        #递归
        #前序遍历,把所有的结果暂存在数组中
        if not root:
            return 0
        
        res=[]
        def dfs(root,res):
            if root.left and not root.left.left and not root.left.right:
                res.append(root.left.val)

            if root.left:
                dfs(root.left,res)
            if root.right:
                dfs(root.right,res)

        dfs(root,res)

        return sum(res)

        ## 后序遍历(左右中),不暂存结果,通过递归函数的返回值来累加求取左叶子数值之和。。
        if not root: 
            return 0
        
        left_left_leaves_sum = self.sumOfLeftLeaves(root.left)  # 左
        right_left_leaves_sum = self.sumOfLeftLeaves(root.right) # 右
        
        cur_left_leaf_val = 0
        if root.left and not root.left.left and not root.left.right: 
            cur_left_leaf_val = root.left.val 
            
        return cur_left_leaf_val + left_left_leaves_sum + right_left_leaves_sum # 中

例八:513. 找树左下角的值

给定一个二叉树的 根节点 root,请找出该二叉树的 最底层 最左边 节点的值。

假设二叉树中至少有一个节点。

递归法

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
 //这段代码凭借前序遍历,首先leftLen>maxLen所以最后的答案肯定是最后一层的节点,又由于先遍历的左,所以最后得到的答案是最左边节点的值
 //得到最底层、最左边 节点值
class Solution {
public:
    int maxLen=INT_MIN;
    int maxleftval;
    void traversal(TreeNode* root,int leftLen){
        if(root->left==nullptr and root->right==nullptr){
            if(leftLen>maxLen){
                maxLen=leftLen;
                maxleftval=root->val;
            }
            return;
        }

        if(root->left){
            leftLen++;
            traversal(root->left,leftLen);
            leftLen--;//回溯
        }
        if(root->right){
            leftLen++;
            traversal(root->right,leftLen);
            leftLen--;
        }
        return;
    }
    int findBottomLeftValue(TreeNode* root) {
        traversal(root,0);
        return maxleftval;
    }

};

层序遍历法

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def findBottomLeftValue(self, root):
        """
        :type root: TreeNode
        :rtype: int
        """
        #递归法
        #在树的最后一行找到最左边的值
        

        #最底层 最左边 节点
        #层序遍历,最后一层的第一个
        if not root:
            return None
        
        from collections import deque
        queue=deque([root])
        res=0
        while queue:
            leng=len(queue) 
            for i in range(leng):
                tmp=queue.popleft()
                if i==0:
                    res=tmp.val
                if tmp.left:
                    queue.append(tmp.left)
                if tmp.right:
                    queue.append(tmp.right)
        return res

例九:112. 路径总和

给你二叉树的根节点 root 和一个表示目标和的整数 targetSum 。判断该树中是否存在 根节点到叶子节点 的路径,这条路径上所有节点值相加等于目标和 targetSum 。如果存在,返回 true ;否则,返回 false 。

叶子节点 是指没有子节点的节点。

递归法:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def hasPathSum(self, root, targetSum):
        """
        :type root: TreeNode
        :type targetSum: int
        :rtype: bool
        """

        def dfs(root,tmp):
            if not root:
                return False
            tmp+=root.val
            if not root.left and not root.right and tmp==targetSum:
                    return True
            if dfs(root.left,tmp) or dfs(root.right,tmp): ##找到即时返回,不再做无谓的寻找
                    return True
            return False

        return dfs(root,0)

迭代法:

/**
 * Definition for a binary tree node.
 * struct TreeNode {
 *     int val;
 *     TreeNode *left;
 *     TreeNode *right;
 *     TreeNode() : val(0), left(nullptr), right(nullptr) {}
 *     TreeNode(int x) : val(x), left(nullptr), right(nullptr) {}
 *     TreeNode(int x, TreeNode *left, TreeNode *right) : val(x), left(left), right(right) {}
 * };
 */
class Solution {
public:
    bool hasPathSum(TreeNode* root, int targetSum) {
        if(root==nullptr) return false;
        stack<pair<TreeNode*,int>> st;
        st.push(pair<TreeNode*,int>(root,root->val));
        while(!st.empty()){
            pair<TreeNode*,int> node=st.top();
            st.pop();
            if(!node.first->left && !node.first->right && targetSum==node.second) return true;
            if(node.first->right){
                st.push(pair<TreeNode*,int>(node.first->right,node.second+node.first->right->val));
            }
            if(node.first->left){
                st.push(pair<TreeNode*,int>(node.first->left,node.second+node.first->left->val));
            }

        }

        return false;
    }
};

例十:113. 路径总和 II

给你二叉树的根节点 root 和一个整数目标和 targetSum ,找出所有 从根节点到叶子节点 路径总和等于给定目标和的路径。

叶子节点 是指没有子节点的节点。

class Solution(object):
    def pathSum(self, root, targetSum):
        """
        :type root: TreeNode
        :type targetSum: int
        :rtype: List[List[int]]
        """
        res=[]
        if not root:
            return res
        def dfs(root,tmp):
            # summ+=root.val
            tmp.append(root.val)
            if not root.left and not root.right and sum(tmp)==targetSum:
                res.append(tmp[:])
                return
            
            if root.left:
                dfs(root.left,tmp)
                tmp.pop() ##回溯

            if root.right:
                dfs(root.right,tmp)
                tmp.pop() ##回溯

        dfs(root,[])

        return res

具体步骤:
在这里插入图片描述

例十一:106. 从中序与后序遍历序列构造二叉树

给定两个整数数组 inorder 和 postorder ,其中 inorder 是二叉树的中序遍历, postorder 是同一棵树的后序遍历,请你构造并返回这颗 二叉树 。

(具体步骤的说明见本篇例四)

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def buildTree(self, inorder, postorder):
        """
        :type inorder: List[int]
        :type postorder: List[int]
        :rtype: TreeNode
        """
        #inorder 和 postorder 都由 不同 的值组成
        def mybuildTree(postorder_left,postorder_right,inorder_left,inorder_right):
            if postorder_left>postorder_right:
                return None
            postorder_root=postorder_right
            inorder_root=index[postorder[postorder_root]] ## 在中序遍历中定位根节点
            root=TreeNode(postorder[postorder_root])
            size_left_subtree = inorder_root - inorder_left

            root.left=mybuildTree(postorder_left,postorder_left+size_left_subtree-1,inorder_left,inorder_root-1)
            root.right=mybuildTree(postorder_left+size_left_subtree,postorder_right-1,inorder_root+1,inorder_right)
            return root

        n=len(postorder)
        index={element:i for i,element in enumerate(inorder)}## 构造哈希映射,帮助我们快速定位根节点
        return mybuildTree(0,n-1,0,n-1)

例十二:654. 最大二叉树

给定一个不重复的整数数组 nums 。 最大二叉树 可以用下面的算法从 nums 递归地构建:

创建一个根节点,其值为 nums 中的最大值。
递归地在最大值 左边 的 子数组前缀上 构建左子树。
递归地在最大值 右边 的 子数组后缀上 构建右子树。
返回 nums 构建的 最大二叉树 。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def constructMaximumBinaryTree(self, nums):
        """
        :type nums: List[int]
        :rtype: TreeNode
        """
        #不重复的整数数组 nums

    # 注意类似用数组构造二叉树的题目,每次分隔尽量不要定义新的数组,而是通过下标索引直接在原数组上操作,这样可以节约时间和空间上的开销。

        def mymaxTree(left,right):
            if left>right: ##由于是左闭右闭区间,left==right可以成立,此时区间内只有一个值
                return None
            
            rootn=max(nums[left:right+1])
            nums_root=index[rootn]
            root=TreeNode(rootn)

            root.left=mymaxTree(left,nums_root-1) ##这里我定义的是左闭右闭区间,也即[left,nums_root-1]内的下标都取到
            root.right=mymaxTree(nums_root+1,right)

            return root

        n=len(nums)
        index={element:i for i,element in enumerate(nums)}
        return mymaxTree(0,n-1)

例十三:617. 合并二叉树

给你两棵二叉树: root1 和 root2 。

想象一下,当你将其中一棵覆盖到另一棵之上时,两棵树上的一些节点将会重叠(而另一些不会)。你需要将这两棵树合并成一棵新二叉树。合并的规则是:如果两个节点重叠,那么将这两个节点的值相加作为合并后节点的新值;否则,不为 null 的节点将直接作为新二叉树的节点。

返回合并后的二叉树。

注意: 合并过程必须从两个树的根节点开始。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def mergeTrees(self, root1, root2):
        """
        :type root1: TreeNode
        :type root2: TreeNode
        :rtype: TreeNode
        """
        def mergeTree(root11,root22,root3):
            if not root11:
                return root22
            if not root22:
                return root11

            root3=TreeNode(root11.val+root22.val)
            root3.left=mergeTree(root11.left,root22.left,root3)
            root3.right=mergeTree(root11.right,root22.right,root3)

            return root3

        return mergeTree(root1,root2,None)##root3初始设为None

可以简化代码:

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def mergeTrees(self, root1, root2):
        """
        :type root1: TreeNode
        :type root2: TreeNode
        :rtype: TreeNode
        """
        if not root1:
            return root2
        if not root2:
            return root1
        root3=TreeNode(root1.val+root2.val)
        root3.left=self.mergeTrees(root1.left,root2.left)
        root3.right=self.mergeTrees(root1.right,root2.right)

        return root3

例十四:700. 二叉搜索树中的搜索

给定二叉搜索树(BST)的根节点 root 和一个整数值 val。

你需要在 BST 中找到节点值等于 val 的节点。 返回以该节点为根的子树。 如果节点不存在,则返回 null 。

# Definition for a binary tree node.
# class TreeNode(object):
#     def __init__(self, val=0, left=None, right=None):
#         self.val = val
#         self.left = left
#         self.right = right
class Solution(object):
    def searchBST(self, root, val):
        """
        :type root: TreeNode
        :type val: int
        :rtype: TreeNode
        """
        if not root:
            return None ##返回类型是TreeNode,所以不能返回[],只能返回None

        if root.val==val:
            return root
        elif root.val>val:
            res=self.searchBST(root.left,val)
        else:
            res=self.searchBST(root.right,val)

        return res

补充:145

为了解上述代码的具体运行流程,最好debug一遍,比如例一的完整代码如下:

import json


class TreeNode(object):
    def __init__(self, val=0, left=None, right=None):
        self.val = val
        self.left = left
        self.right = right
class Solution(object):
	def preorderTraversal(self, root):
		"""
        :type root: TreeNode
        :rtype: List[int]
        """

		def traversal(root, res):
			if root == None:
				return
			res.append(root.val)  # 中
			traversal(root.left, res)  # 左
			traversal(root.right, res)  # 右

		res = []
		traversal(root, res)
		return res


def stringToTreeNode(input):
	input = input.strip()
	input = input[1:-1]
	if not input:
		return None

	inputValues = [s.strip() for s in input.split(',')]
	root = TreeNode(int(inputValues[0]))
	nodeQueue = [root]
	front = 0
	index = 1
	while index < len(inputValues):
		node = nodeQueue[front]
		front = front + 1

		item = inputValues[index]
		index = index + 1
		if item != "null":
			leftNumber = int(item)
			node.left = TreeNode(leftNumber)
			nodeQueue.append(node.left)

		if index >= len(inputValues):
			break

		item = inputValues[index]
		index = index + 1
		if item != "null":
			rightNumber = int(item)
			node.right = TreeNode(rightNumber)
			nodeQueue.append(node.right)
	return root


def integerListToString(nums, len_of_list=None):
	if not len_of_list:
		len_of_list = len(nums)
	return json.dumps(nums[:len_of_list])


def main():
	import sys
	def readlines():
		for line in sys.stdin:
			yield line.strip('\n')

	lines = readlines()
	while True:
		try:
			line = lines.__next__()
			root = stringToTreeNode(line)

			ret = Solution().preorderTraversal(root)

			out = integerListToString(ret)
			print(out)

		except StopIteration:
			break


if __name__ == '__main__':
	main()
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值