Leecode——数据结构练习

这篇博客详细探讨了LeetCode中的数据结构问题,涵盖了链表、栈和队列的算法实现,以及二进制位运算的应用。在链表部分,讲解了反转链表、合并链表等操作;栈和队列中讨论了如何利用它们解决逆波兰表达式和层次遍历等问题;此外,还深入介绍了二进制位运算的技巧,如取指定位、反转和计算二进制中1的个数等。
 
一、二叉树
前序遍历、中序遍历、后序遍历:
1.前序遍历:
     def preorderTraversal(self, root: TreeNode) -> List[int]:
        if root == None:
            return []
        # 分别记录遍历结果,存储栈
        result, istack = [], []
        while root != None or len(istack) != 0:
            # 嵌套循环
            while root != None:
                # 前序遍历,压入栈前先输出
                result.append(root.val)
                istack.append(root)
                root=root.left
            # 栈弹出
            root = istack[-1]
            istack = istack[:-1]
            root = root.right
        return result

2.中序遍历:

    def inorderTraversal(self, root: TreeNode) -> List[int]:
        if root == None:
            return []
        # 分别记录遍历结果,存储栈
        result, istack = [], []
        while root != None or len(istack) != 0:
            while root != None:
                istack.append(root)
                root = root.left
            # 中序遍历,等左子树压入栈完毕,再从栈输出
            cur = istack[-1]
            result.append(cur.val)
            istack = istack[:-1]
            root = cur.right
        return result

3.后序遍历:

    def postorderTraversal(self, root: TreeNode) -> List[int]:
        if root == None:
            return []
        # 分别记录遍历结果,存储栈,后序遍历必要的前一个输出节点记录
        result, istack, lastnode = [], [], None
        while root != None or len(istack) != 0:
            while root != None:
                istack.append(root)
                root = root.left
            # 左子树压入栈后,判断当前节点是否可输出
            cur = istack[-1]
            # 如果当前节点无右子树,或者右子树已经输出,则该点可输出
            if cur.right == None or cur.right == lastnode:
                istack = istack[:-1]
                result.append(cur.val)
                lastnode = cur
            # 否则继续将该点右子树入栈,再继续循环
            else:
                root = cur.right
        return result

深度搜索DFS,层次搜索BFS:

1.层次搜索/遍历
    def levelOrder(self, root: TreeNode) -> List[List[int]]:
        if root == None:
            return []
        # 层序遍历,需要借助队列记录
        result, iqueue = [], []
        # 队列需要先入队
        iqueue.append(root)
        while len(iqueue) != 0:
            # 遍历当前层之前,先记录该层的个数,以便队列边记录边遍历
            l, temp = len(iqueue), []
            for i in range(0, l):
                # 遍历时,依次取出和输出队中的点,并将子树入队
                cur = iqueue[0]
                iqueue = iqueue[1:]
                temp.append(cur.val)
                if cur.left != None:
                    iqueue.append(cur.left)
                if cur.right != None:
                    iqueue.append(cur.right)
            result.append(temp)
        return result

分治法:递归返回条件+分段处理+合并结果(快速排序、归并排序、二叉树)

1.简单分治法:用于计算二叉树的最大深度
    def maxDepth(self, root: TreeNode) -> int:
        if root == None:
            return 0
        left = self.maxDepth(root.left)
        right = self.maxDepth(root.right)
        return left + 1 if left > right else right + 1

2.判断是否为平衡二叉树:

    def isBalanced(self, root: TreeNode) -> bool:
        if self.judge(root) == -1:
            return False
        else:
            return True
    def judge(self, root: TreeNode) -> int:
        if root == None:
            return 0
        left = self.judge(root.left)
        right = self.judge(root.right)
        # 借助层数来记录是否平衡,如果为-1,则直接返回不平衡
        if left == -1 or right == -1 or left - right > 1 or right - left > 1:
            return -1
        else:
            return left + 1 if left > right else right + 1

3.找出二叉树中最大路径和【hard

    def maxPathSum(self, root: TreeNode) -> int:
        # 最大和:左/右子树最大和,左右子树加根节点的最大和
        summax = self.find(root)
        return summax[1]

    def find(self, root: TreeNode) -> List[int]:
        if root == None:
            return [0, float('-inf')]
        # 分治
        left = self.find(root.left)
        right = self.find(root.right)
        result = []
        # 合并规整,先求单边值,再求最大和
        if left[0] > right[0]:
            result.append(max(left[0] + root.val, 0))
        else:
            result.append(max(right[0] + root.val, 0))
        result.append(max(max(left[1], right[1]), (left[0] + right[0] + root.val)))
        return result

4.找出二叉树的公共祖先

    def lowestCommonAncestor(self, root: 'TreeNode', p: 'TreeNode', q: 'TreeNode') -> 'TreeNode':
        if root == None:
            return root
        if root == p or root == q:
            return root
        # 分治
        left = self.lowestCommonAncestor(root.left, p, q)
        right = self.lowestCommonAncestor(root.right, p, q)
        # 归并整合,返回为空则未找到,返回不为空则找到
        if left != None and right != None:
            return root
        if left != None:
            return left
        if right != None:
            return right
        return None

BFS层次遍历:

1.锯齿形层次遍历:
    def zigzagLevelOrder(self, root: TreeNode) -> List[List[int]]:
        if root == None:
            return []
        # 层次遍历需要借助队列顺序,锯齿形需要逆转标记
        result, iqueue, iturn = [], [], True
        iqueue.append(root)
        while len(iqueue) > 0:
            temp, l = [], len(iqueue)
            for i in range(0, l):
                cur = iqueue[0]
                iqueue = iqueue[1:]
                if iturn:
                    temp.append(cur.val)
                else:
                    temp.insert(0, cur.val)
                if cur.left != None:
                    iqueue.append(cur.left)
                if cur.right != None:
                    iqueue.append(cur.right)
            if iturn:
                iturn = False
            else:
                iturn = True
            result.append(temp)
        return result

2.判定是否为有效二叉搜索树【medium

    def isValidBST(self, root: TreeNode) -> bool:
        res = self.helper(root)
        if res[0] == 0:
            return False
        else:
            return True
    def helper(self, root: TreeNode) -> List[int]:
        # 结果记录,分别为0是否有效,1树的最大值,2树的最小值
        if root == None:
            return [1, float('-inf'), float('-inf')]
        # 分治
        left = self.helper(root.left)
        right = self.helper(root.right)
        # 整合:先判定无效情况
        if left[0] == 0 or right[0] == 0:
            return [0, float('-inf'), float('-inf')]
        if left[1] != float('-inf') and left[1] >= root.val:
            return [0, float('-inf'), float('-inf')]
        if right[2] != float('-inf') and right[2] <= root.val:
            return [0, float('-inf'), float('-inf')]
        # 节点为有效时,节点最大值为右子树的最大值,最小值为左子树的最小值,否则最大最小值为本身
        result = [1, root.val, root.val]
        if right[1] != float('-inf'):
            result[1] = right[1]
        if left[2] != float('-inf'):
            result[2] = left[2]
        return result

3.二叉搜索树中插值:

    def insertIntoBST(self, root: TreeNode, val: int) -> TreeNode:
        if root == None:
            root = TreeNode()
            root.val = val
            return root
        if root.val == val:
            return root
        elif val < root.val:
            root.left = self.insertIntoBST(root.left, val)
        else:
            root.right = self.insertIntoBST(root.right, val)
        return root

二、链表

链表基本操作:
1.删除全部的重复元素
    def deleteDuplicates(self, head: ListNode) -> ListNode:
        pre = ListNode()
        pre.next = head
        head, last = pre, float('inf')
        # 删除重复的额外点,只需要一个指针滑动,判断当前点和下一点(如有);
        # 而删除全部重复点,则需要空指针领头,进行领头后续两个节点的判断(无两个节点则无需判断)。
        while head.next != None and head.next.next != None:
            if head.next.val == head.next.next.val:
                last = head.next.val
                while head.next != None and head.next.val == last:
                    head.next = head.next.next
            else:
                head = head.next
        return pre.next

2.反转链表

    def reverseList(self, head: ListNode) -> ListNode:
        pre = ListNode()
        pre.next = head
        while head.next != None:
            # 记录下一个节点
            last = head.next
            # 将当前节点next指向下一个节点的next
            head.next = last.next
            # 下一个节点next指向空指针next
            last.next = pre.next
            # 将空指针移动至最左
            pre.next = last
        return pre.next

3.将指定段落的链表反转【medium

    def reverseBetween(self, head: ListNode, m: int, n: int) -> ListNode:
        if head == None or m == n:
            return head
        # 先进行小节点检索
        point = ListNode()
        point.next = head
        head = point
        count = 1
        while count < m:
            head = head.next
            count += 1
        pre, mid = head, head.next
        head = head.next
        last = head
        # 用head作为原始遍历顺序指针,last记录移动的前一个结点
        while count <= n and head != None:
            # 将head指针的下一个记录,将当前节点的指针指向上一个节点
            temp = head.next
            head.next = last
            # 移动上一个节点,并将head指针放在原来的下一个
            last = head
            head = temp
            count += 1
        pre.next = last
        mid.next = head
        return point.next

4.拼接两个有序链表

    def mergeTwoLists(self, l1: ListNode, l2: ListNode) -> ListNode:
        # 将合并后的表新起一个空指针作为起点(表头)
        result = ListNode()
        point = result
        while l1 != None and l2 != None:
            if l1.val <= l2.val:
                point.next = l1
                l1 = l1.next
            else:
                point.next = l2
                l2 = l2.next
            point = point.next
        if l1 != None:
            point.next = l1
        if l2 != None:
            point.next = l2
        return result.next

链表分隔与排序:

1.将链表根据值分隔为左小右大
    def partition(self, head: ListNode, x: int) -> ListNode:
        # 需要用空指针作为原始起点的记录,用额外的表记录比x大的节点,再将结果并至指针末尾
        result, pre = ListNode(), ListNode()
        pre.next = head
        bigger, head = result, pre
        while head.next != None:
            if head.next.val < x:
                head = head.next
            else:
                # 将大值节点记录,移动指针,同时将大值节点链入额外记录链表中
                node = head.next
                head.next = node.next
                bigger.next = node
                bigger = bigger.next
        bigger.next = None
        head.next = result.next
        return pre.next

2.归并排序【medium】

    def sortList(self, head: ListNode) -> ListNode:
        return self.mergeSort(head)
    
    def findMiddle(self, head: ListNode) -> ListNode:
        # 用快慢指针来寻找中间节点
        slow = head
        fast = head.next
        while fast != None and fast.next != None:
            fast = fast.next.next
            slow = slow.next
        return slow
    # 拼接两个有序链表
    def mergeTwo(self, l1: ListNode, l2: ListNode) -> ListNode:
        pre = ListNode()
        point = pre
        while l1 != None and l2 != None:
            if l1.val < l2.val:
                point.next = l1
                l1 = l1.next
            else:
                point.next = l2
                l2 = l2.next
            point = point.next
        if l1 != None:
            point.next = l1
        if l2 != None:
            point.next = l2
        return pre.next

    def mergeSort(self, head: ListNode) -> ListNode:
        # 分治法要点1:递归返回确定,这里对至少2个节点排序,故而要有两个判断条件
        if head == None or head.next == None:
            return head
        mid = self.findMiddle(head)
        last = mid.next
        mid.next = None
        # 分治法要点2:分两部分递归,利用快慢指针找到中间节点
        left = self.mergeSort(head)
        right = self.mergeSort(last)
       # 分治法要点3:归并整合两部分,用合并有序链表的方法
        return self.mergeTwo(left, right)

3.将链表按照1, n, 2, n-1, 3, n-2, ..., 的顺序排列

    def reorderList(self, head: ListNode) -> None:
        # 思路:从中间破开链表,反转后链,再合并
        if head == None or head.next == None:
            return head
        mid = self.findMiddle(head)
        last = self.reverseList(mid.next)
        mid.next = None
        head = self.mergeTwo(head, last)

    def findMiddle(self, head: ListNode) -> ListNode:
        slow, fast = head, head.next
        while fast != None and fast.next != None:
            fast = fast.next.next
            slow = slow.next
        return slow
    
    def reverseList(self, head: ListNode) -> ListNode:
        pre = ListNode()
        pre.next = head
        while head.next != None:
            last = head.next
            head.next = last.next
            last.next = pre.next
            pre.next = last
        return pre.next
    
    def mergeTwo(self, left: ListNode, right: ListNode) -> ListNode:
        pre, isleft = ListNode(), True
        point = pre
        while left != None and right != None:
            if isleft:
                point.next = left
                left = left.next
                isleft = False
            else:
                point.next = right
                right = right.next
                isleft = True
            point = point.next
        if left != None:
            point.next = left
        if right != None:
            point.next = right
        return pre.next

环状链表:

1.判断链表是否有环
    def hasCycle(self, head: ListNode) -> bool:
        if head == None:
            return False
        # 快指针用head表示,相交时当前点即为交汇点;
        # 如用head.next表示,则相交点为下一个点
        slow, fast = head, head.next
        # 仅需判断快指针
        while fast != None and fast.next != None:
            if slow == fast:
                return True
            slow = slow.next
            fast = fast.next.next
        return False

2.找出带环链表的入环点    

    def detectCycle(self, head: ListNode) -> ListNode:
        if head == None:
            return head
        # 相交点时,快慢指针分别走过a+b,a+n(b+c),c表示环剩下的长度;
        # 得2(a+b)=a+n(b+c),即a=c+(n-1)(b+c),表示a的长度为n-1圈的环+c;
        # 而慢指针继续走c即可回到入环点,再经过n-1圈仍然在入环点;
        slow, fast = head, head.next
        while fast != None and fast.next != None:
            if fast == slow:
                fast = head
                # 因为一开始fast=head.next,此时slow.next才是真当前点
                slow = slow.next
                while fast != slow:
                    fast = fast.next
                    slow = slow.next
                return slow
            fast = fast.next.next
            slow = slow.next
        return None

回文链表:

1.判断回文链表
    def isPalindrome(self, head: ListNode) -> bool:
        if head == None or head.next == None:
            return True
        # 思路:与前面置换插入排序类似,采用中点截断、反转后链、再比较的做法。
        slow, fast = head, head.next
        while fast != None and fast.next != None:
            slow = slow.next
            fast = fast.next.next
        last = self.reverseList(slow.next)    
        slow.next = None 
        while last != None and head != None:
            if last.val != head.val:
                return False
            last, head = last.next, head.next
        return True  

    def reverseList(self, head: ListNode) -> ListNode:
        if head == None:
            return head
        pre = ListNode()
        # 切记,在反转链表时,空指针不需要head辅助
        pre.next = head
        while head.next != None:
            node = head.next
            head.next = node.next
            node.next = pre.next
            pre.next = node
        return pre.next

2.深拷贝链表【medium

   def copyRandomList(self, head: 'Node') -> 'Node':
        if head == None:
            return head
        point = head
        while point != None:
            node = Node(point.val, point.next)
            point.next = node
            point = node.next
        point = head
        # 很精妙,采用判断前一个节点为非空,来操作空节点
        while point != None:     
            if point.random != None:
                point.next.random = point.random.next
            point = point.next.next
            # 原做法
            # node = point.random
            # if node != None:
            #     point.random = node.next
            # if point.next != None:
            #     point = point.next.next
            # else:
            #     point = point.next
        point = head.next
        while head != None and head.next != None:
            # 很精妙,采用指针穿线的方法
            node = head.next
            head.next = head.next.next
            head = node
        return point    

三、栈和队列

1.最小栈
class MinStack:
    def __init__(self,):
        self.istack = []
        self.minstack = []
        # 采用辅助栈做法,记录每个位置的最小值
    
    def push(self, x: int) -> None:
        self.istack.append(x)
        if len(self.minstack) != 0 and self.minstack[-1] < x:
            temp = self.minstack[-1]
            self.minstack.append(temp)
        else:
            self.minstack.append(x)

    def pop(self) -> None:
        if len(self.istack) == 0:
            return
        self.istack = self.istack[:-1]
        self.minstack = self.minstack[:-1]

    def top(self) -> int:
        if len(self.istack) == 0:
            return 0
        return self.istack[-1]

    def getMin(self) -> int:
        if len(self.istack) == 0:
            return float('inf')
        return self.minstack[-1]

2.利用栈进行逆波兰表达式求解

class Solution:
    def evalRPN(self, tokens: List[str]) -> int:
        if len(tokens) == 0:
            return 0
        istack = []
        for i in range(0, len(tokens)):
            # 关键:会有二位数,因此先判断是否符号,并且是符号还要判断是否有已有两个值在栈中
            if tokens[i] not in ["+", "-", "*", "/"]:
                istack.append(int(tokens[i]))
            elif len(istack) < 2:
                break
            else:
                a, b = istack[-2], istack[-1]
                istack = istack[:-2]
                if tokens[i] == "+":
                    istack.append(a + b)
                elif tokens[i] == "-":
                    istack.append(a - b)
                elif tokens[i] == "*":
                    istack.append(a * b)
                elif tokens[i] == "/":
                    istack.append(int(a / b))
                else:
                    pass
        if len(istack) == 1:
            return istack[0]
        else:
            return 0

3.字符串解码

    def decodeString(self, s: str) -> str:
        istack = []
        for i in range(0, len(s)):
            if s[i] == ']':
                # 找字符串
                temp = []
                while len(istack) > 0 and istack[-1] != '[':
                    temp.insert(0, istack[-1])
                    istack = istack[:-1]
                istack = istack[:-1]
                # 找数字
                number = 1
                ilen = len(istack)
                while ilen >= number and istack[ilen - number] in ['0','1','2','3','4','5','6','7','8','9']:
                    number += 1
                # 数字范围:[len - i + 1, len - 1]
                res = int(''.join(istack[ilen - number + 1:]))
                istack = istack[:ilen - number + 1]
                # 复制
                for i in range(0, res):
                    istack.extend(temp)
            else:
                istack.append(s[i])
        return ''.join(istack)

4.克隆图

    def cloneGraph(self, node: 'Node') -> 'Node':
        # 关键点:用visited记录新建的节点,以连接
        visited = {}
        return self.cloneg(node, visited)

    def cloneg(self, node: 'Node', visited: dict) -> 'Node':
        if node == None:
            return node  
        # visited中能找到新建节点,则直接返回节点
        if visited.get(node) != None:
            return visited[node]
        newnode = Node(node.val, [])
        visited[node] = newnode
        for n in range(0, len(node.neighbors)):
            newnode.neighbors.append(self.cloneg(node.neighbors[n], visited))
        return newnode

5.小岛数量【medium

    def numIslands(self, grid: List[List[str]]) -> int:
        count = 0
        # 按数组顺序扫描
        for i in range(0, len(grid)):
            for j in range(0, len(grid[0])):
                if grid[i][j] == "1" and self.dfs(grid, i, j) >= 1:
                    count += 1
        return count

    def dfs(self, grid: List[List[str]], i: int, j: int) -> int:
        if i < 0 or j < 0 or i >= len(grid) or j >= len(grid[0]):
            return 0
        if grid[i][j] == "1":
            grid[i][j] = "0"
            # 将grid列表传入函数与(对象一样)属于引用传递,访问后改值相当于列表自带访问记录功能
            return self.dfs(grid, i-1, j) + self.dfs(grid, i, j-1) +\
                self.dfs(grid, i+1, j) + self.dfs(grid, i, j+1) + 1
        return 0

6.求条状图中的最大矩形面积【单调栈hard

    def largestRectangleArea(self, heights: List[int]) -> int:
        # 1.采用宽度法,选取左右点固定区间,直接取高度,O(n2)
        # 2.采用高度法,对于每根柱子求取最大宽度
        # 固定高度,求宽度,即找左右侧:
        # 左侧比当前高度低的第一根柱子;右侧比当前高度低的第一根柱子
        res, istack = 0, []
        # 在矩形中加入左右哨兵以求宽度
        heights = [0] + heights + [0]
        for i in range(len(heights)):
            # 每次入栈,必须保证矩形高度为递增的
            while istack and heights[istack[-1]] > heights[i]:
                last= istack.pop()
                res = max(res, heights[last]*(i - 1 - istack[-1]))
            istack.append(i)
        return res

队列

1.用栈实现队列
class MyQueue:
    def __init__(self):
        self.prestack = []
        self.poststack = []

    def push(self, x: int) -> None:
        while len(self.poststack) != 0:
            self.prestack.append(self.poststack.pop())
        self.prestack.append(x)

    def pop(self) -> int:
        while self.prestack:
            self.poststack.append(self.prestack.pop())
        if self.poststack:
            return self.poststack.pop()
        return -1


    def peek(self) -> int:
        while self.prestack:
            self.poststack.append(self.prestack.pop())
        if self.poststack:
            return self.poststack[-1]
        return -1        

    def empty(self) -> bool:
        if not self.prestack and not self.poststack:
            return True
        return False

2.二叉树层次遍历

3.0-1矩阵,找非0位置到0的距离【medium】
    def updateMatrix(self, matrix: List[List[int]]) -> List[List[int]]:
        # 根据广度优先搜索,从外部向内包围
        if not matrix:
            return matrix
        row, col = len(matrix), len(matrix[0])
        iqueue = []
        for i in range(row):
            for j in range(col):
                # 从外包围,先将外围入队
                if matrix[i][j] == 0:
                    iqueue.append([i,j])
                # 直接用值(-1)区分需要修改的点
                else:
                    matrix[i][j] = -1
        while len(iqueue) != 0:
            point_i, point_j = iqueue[0][0], iqueue[0][1]
            iqueue = iqueue[1:]
            newpoint = [[point_i-1, point_j], [point_i+1, point_j], [point_i, point_j-1], [point_i, point_j+1]]
            for n in newpoint:
                ii, jj = n[0], n[1]
                # 修改过的点为下一层入队点
                if ii >= 0 and ii < row and jj >= 0 and jj < col and matrix[ii][jj] == -1:
                    matrix[ii][jj] = matrix[point_i][point_j] + 1
                    iqueue.append([ii, jj])
        return matrix

 

四、二进制(位运算)【https://blog.csdn.net/holmofy/article/details/79360859

6个位运算符【&  |  ^  ~  <<  >>】
  • &(0清零,1保留):取指定位;判断奇偶 (a&1)==0或a&(-a)==0
  • |(有1则1,0保留):改值(用1)
  • ^(同0异1,满足结合律、自反性):反转指定位;
  • ~
从数组中找出只出现1次的数字:
1.2次中找1次:【异或】
    def singleNumber(self, nums: List[int]) -> int:
        res = 0
        for n in nums:
            res = res ^ n
        return res

2.3次中找1次:【异或、与、非的组合】

    def singleNumber(self, nums: List[int]) -> int:
        once, twice = 0, 0
        # n,once,twice 
        # 0 0 0 
        # 0 1 0 
        # 0 0 1
        # 1 0 0
        # 1 1 0 
        # 1 0 1
        # 对于n=1而言,3个1最终仍使once=0,实现3个数的位运算保证 
        for n in nums:
            once = once ^ n & ~twice 
            twice = twice ^ n & ~once
        return once

3.2次中找2个1次:

    def singleNumber(self, nums: List[int]) -> List[int]:
        # 1.求x和y的异或值。
        # 2.求这个异或值最右位的1
        # 3.找出x和y中是谁造成了这个最右位的1,以分离x和y
        res = 0
        for n in nums:
            res ^= n
        # res = x ^ y
        # 取最右一位的1:res&(~res + 1)、res&(-res)、res&(res-1)^res
        lastbit = (res&(res-1))^res
        x = 0
        for n in nums:
            if n & lastbit != 0:
                x ^= n
        return [x, res^x]

计算二进制:

1.计算二进制中1的个数:

    def hammingWeight(self, n: int) -> int:
        count = 0
        while n != 0:
            # 获取最后一位判断
            if n & (-n) == 1:
                count += 1
            n = n >> 1
        return count

2.反转32位无符号整数二进制

    def reverseBits(self, n: int) -> int:
        res = 0
        for i in range(32):
            res = res << 1 
            # 获取最后一位判断
            if n & 1 == 1:
                res += 1
            n = n >> 1
        return res 

3.求区间数二进制的与值

    def rangeBitwiseAnd(self, m: int, n: int) -> int:
        # 因为相邻的两个数必有1~2位不相同的位置,可以找规律:
        # 100100
        # 100101
        # 100110
        # 100111
        # 101000
        # 因为m与n的相同前缀后分别为0,1(SSS0XXX,SSS1XXX)
        # 通过m与n的不断舍取得到相同前缀即可
        count = 0
        while m != n:
            m = m >> 1
            n = n >> 1
            count += 1
        # 得到相同前缀,将末尾0补足
        return m << count

 

 
 
 
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值