LeetCode刷题笔记(Java)---第621-640题

前言

需要开通vip的题目暂时跳过

笔记导航

点击链接可跳转到所有刷题笔记的导航链接

622. 设计循环队列

设计你的循环队列实现。 循环队列是一种线性数据结构,其操作表现基于 FIFO(先进先出)原则并且队尾被连接在队首之后以形成一个循环。它也被称为“环形缓冲器”。

循环队列的一个好处是我们可以利用这个队列之前用过的空间。在一个普通队列里,一旦一个队列满了,我们就不能插入下一个元素,即使在队列前面仍有空间。但是使用循环队列,我们能使用这些空间去存储新的值。

你的实现应该支持如下操作:

  • MyCircularQueue(k): 构造器,设置队列长度为 k 。

  • Front: 从队首获取元素。如果队列为空,返回 -1 。

  • Rear: 获取队尾元素。如果队列为空,返回 -1 。

  • enQueue(value): 向循环队列插入一个元素。如果成功插入则返回真。

  • deQueue(): 从循环队列中删除一个元素。如果成功删除则返回真。

  • isEmpty(): 检查循环队列是否为空。

  • isFull(): 检查循环队列是否已满。

  • 解答

    class MyCircularQueue {
        Node head;
        Node tail;
    
        public MyCircularQueue(int k) {
            this.head = new Node(-1);
            Node p = head;
            k--;
            while(k > 0){
                p.next = new Node(-1);
                p = p.next;
                k--;
            }
            p.next = head;
            tail = head;
        }
        
        public boolean enQueue(int value) {
            if(tail.next == head)return false;
            if(tail.val == -1){
                tail.val = value;
                return true;
            }
            tail = tail.next;
            tail.val = value;
            return true;
        }
        
        public boolean deQueue() {
            if(head.val != -1){
                if(head == tail){
                    head.val = -1;
                }else{
                    head.val = -1;
                    head = head.next;
                }
                return true;
            }
            return false;
        }
        
        public int Front() {
            return head.val;
        }
        
        public int Rear() {
            return tail.val;
        }
        
        public boolean isEmpty() {
            return head.val == -1;
        }
        
        public boolean isFull() {
            return tail.next == head;
        }
    
        class Node{
            int val;
            Node next;
            public Node(int val){
                this.val = val;
            }
        }
    }
    
  • 分析

    1. head指向队头,tail指向队尾
    2. 若head.val == -1 说明队空
    3. tail的后继指向head说明队满
    4. 进队的时候,若tail.val == -1 只需要修改tail的值,否则的话 tail要移动到它的后继 再修改值
    5. 出队的时候,若head == tail 那么只需要修改hea的值为-1。否则的话 head需要移动到它的后继
  • 提交结果在这里插入图片描述

623. 在二叉树中增加一行

给定一个二叉树,根节点为第1层,深度为 1。在其第 d 层追加一行值为 v 的节点。

添加规则:给定一个深度值 d (正整数),针对深度为 d-1 层的每一非空节点 N,为 N 创建两个值为 v 的左子树和右子树。

将 N 原先的左子树,连接为新节点 v 的左子树;将 N 原先的右子树,连接为新节点 v 的右子树。

如果 d 的值为 1,深度 d - 1 不存在,则创建一个新的根节点 v,原先的整棵树将作为 v 的左子树。

在这里插入图片描述

在这里插入图片描述

  • 解答

    public TreeNode addOneRow(TreeNode root, int v, int d) {
            List<TreeNode> list = new ArrayList<>();
            list.add(root);
            int depth = 1;
            if(d == 1){
                TreeNode h = new TreeNode(v);
                h.left = root;
                return h;
            }
            while(!list.isEmpty()){
                List<TreeNode> temp = new ArrayList<>();
                for(TreeNode node:list){
                    if(node.left != null){
                        temp.add(node.left);
                    }
                    if(node.right != null){
                        temp.add(node.right);
                    }
                    if(depth == d - 1){
                        TreeNode l = new TreeNode(v);
                        TreeNode r = new TreeNode(v);
                        l.left = node.left;
                        r.right = node.right;
                        node.left = l;
                        node.right = r;
                    }
                }
                list = temp;
                depth++;
            }
            return root;
        }
    
  • 分析

    1. 若是在第一层添加,那么直接新建一个值为v的结点h,左孩子指向root 返回h
    2. 否则就是层次遍历,找到第d层,进行插入值为v的结点。
  • 提交结果在这里插入图片描述

628. 三个数的最大乘积

给定一个整型数组,在数组中找出由三个数组成的最大乘积,并输出这个乘积。

在这里插入图片描述

  • 解答

    //方法1
    public int maximumProduct(int[] nums) {
            Arrays.sort(nums);
            int len = nums.length;
            int num1 = nums[len-1] * nums[len-2] * nums[len-3];
            int num2 = nums[0] * nums[1] * nums[len-1];
            return Math.max(num1,num2);
        }
    //方法2
    public int maximumProduct(int[] nums) {
            if (nums.length < 3) {
                return 0;
            }
            int min1 = Integer.MAX_VALUE, min2 = Integer.MAX_VALUE;
            int max1 = Integer.MIN_VALUE, max2 = Integer.MIN_VALUE, max3 = Integer.MIN_VALUE;
            for (int n : nums) {
                if (n < min1) {
                    min2 = min1;
                    min1 = n;
                } else if (n < min2) {
                    min2 = n;
                } 
                 if (n > max1) {
                    max3 = max2;
                    max2 = max1;
                    max1 = n;
                } else if (n > max2) {
                    max3 = max2;
                    max2 = n;
                } else if (n > max3) {
                    max3 = n;
                }
            }
            return Math.max(min1 * min2 * max1, max1 * max2 * max3);
        }
    
    
  • 分析

    1. 方法1 排序
    2. 两种情况存在最大值,一种是排序后最后三个数字的乘积
    3. 第二种是,最小的两位数是负数,负负等正,再✖️上最后一位数字
    4. 比较上面两种情况的大小,返回较大者
    5. 方法2 一次遍历
    6. 上面两种情况,实际上只需要用5个数字,所以一次遍历找到这5个数字即可。
  • 提交结果

    方法1在这里插入图片描述

    方法2在这里插入图片描述

629. K个逆序对数组

给出两个整数 n 和 k,找出所有包含从 1 到 n 的数字,且恰好拥有 k 个逆序对的不同的数组的个数。

逆序对的定义如下:对于数组的第i个和第 j个元素,如果满i < j且 a[i] > a[j],则其为一个逆序对;否则不是。

由于答案可能很大,只需要返回 答案 mod 109 + 7 的值。

在这里插入图片描述

  • 解答

    public int kInversePairs(int n, int k) {
            int[][] dp = new int[n + 1][k + 1];
            int M = 1000000007;
            for (int i = 1; i <= n; i++) {
                for (int j = 0; j <= k && j <= i * (i - 1) / 2; j++) {
                    if (i == 1 && j == 0) {
                        dp[i][j] = 1;
                        break;
                    } else if (j == 0)
                        dp[i][j] = 1;
                    else {
                        int val = (dp[i - 1][j] + M - ((j - i) >= 0 ? dp[i - 1][j - i] : 0)) % M;
                        dp[i][j] = (dp[i][j - 1] + val) % M;
                    }
                }
            }
            return dp[n][k];
        }
    
  • 分析

    1. dp[i] [j] 表示1-i 的数字的排列组合 恰好包含j个逆序对的个数。
    2. 考虑状态转移,i+1这个数字比1-i都要大,若i+1放在最后,那么逆序对个数不变,若i+1放到倒数第二个位置,那么逆序对+1,i+1放到倒数第三个位置,那么逆序对+2
    3. 所以状态转移方程就出来了
    4. dp[i] [j] = dp[i-1] [j] + dp[i-1] [j-1] + … + dp[i-1] [j-i+1]
    5. dp[i] [j] 与dp[i-1] [j]相比较,可以得到
    6. dp[i] [j] - dp[i - 1] [j] = dp[i] [j-1] - dp[i-1] [j-i] => dp[i] [j] = dp[i - 1] [j] + dp[i] [j-1] - dp[i - 1] [j-i]
    7. 边界条件dp[i] [0] = 1
    8. dp[n] [k] 就是1-n的数字组合 k个逆序对 的组合数
  • 提交结果在这里插入图片描述

630. 课程表 III

这里有 n 门不同的在线课程,他们按从 1 到 n 编号。每一门课程有一定的持续上课时间(课程时间)t 以及关闭时间第 d 天。一门课要持续学习 t 天直到第 d 天时要完成,你将会从第 1 天开始。

给出 n 个在线课程用 (t, d) 对表示。你的任务是找出最多可以修几门课。

在这里插入图片描述

  • 解答

    public int scheduleCourse(int[][] courses) {
            Arrays.sort(courses,(a,b)->{
                return a[1] - b[1];
            });
            PriorityQueue<int[]> queue = new PriorityQueue<>(new Comparator<int[]>(){
                public int compare(int[] o1,int[] o2){
                    return o2[0] - o1[0];
                }
            });
            int time = 0;
            for(int[] course:courses){
                if(time + course[0] <= course[1]){
                    queue.offer(course);
                    time += course[0];
                }else{
                    if(!queue.isEmpty() && queue.peek()[0] > course[0]){
                        time += course[0] - queue.poll()[0];
                        queue.offer(course);
                    }
                }
            }
            return queue.size();
        }
    
  • 分析

    1. 根据结束时间升序排序。
    2. 利用大顶堆,根据课程的持续时间降序排序。
    3. 遍历排序后的数组,若当前时间加上持续时间小于等于当前的结束时间,说明可以完成这个课程。
    4. 那么就记录下上完这个课的累积时间time
    5. 若不满足上面的条件,说明前面的累积时间太长了,加上现在这门课的时间,会超过关闭的时间,
    6. 所以要想办法让累积时间变短。
    7. 这也就是大顶堆的作用,记录下上过的课的课时。
    8. 若当前时间加上当前这门课的时长超过了 这门课的关闭时间,从大顶堆中选择一个课时最长的课取出,若该课的课时大于当前遍历的这门课的课时,几更新累积市场,并将当前遍历的课放入大顶堆当中。
    9. 这样累积的时间就变短了,有利于上更多的课。
    10. 最后返回大顶堆的大小即可。
  • 提交结果在这里插入图片描述

632. 最小区间

你有 k 个 非递减排列 的整数列表。找到一个 最小 区间,使得 k 个列表中的每个列表至少有一个数包含在其中。

我们定义如果 b-a < d-c 或者在 b-a == d-c 时 a < c,则区间 [a,b] 比 [c,d] 小。

在这里插入图片描述

在这里插入图片描述

  • 解答

    public int[] smallestRange(List<List<Integer>> nums) {
            
            List<int[]> list = new ArrayList<>();
            int k = nums.size();
            for(int i = 0;i < k;i++){
                List<Integer> l = nums.get(i);
                for(int num : l){
                    list.add(new int[]{num,i});
                }
            }
            Collections.sort(list, Comparator.comparingInt(o -> o[0]));
            int[] res = new int[2];
            int[] count = new int[k];
    
            int temp = 0;
            int j = 0;
    
            for(int i = 0;i < list.size();i++){
                if(count[list.get(i)[1]]++ == 0) temp++;
                if(temp == k){
                    while(count[list.get(j)[1]] > 1)count[list.get(j++)[1]]--;
                    if((res[0] == 0 && res[1] == 0) || res[1] - res[0] > list.get(i)[0] - list.get(j)[0])
                        res = new int[]{list.get(j)[0],list.get(i)[0]};
                }
            }
    
            return res;
        }
    
  • 分析

    1. 将所有的数字升序排序,并标记处它来自第几组列表。
    2. list中记录的一个元素表示 数值以及对应的来自第几组列表。
    3. count数组用来统计各个列表中数字出现的次数。
    4. res数组记录答案区间。
    5. 遍历list
    6. 若当前count中记录的这一组数字出现的次数为0,那么temp++,并且count中这一组数字出现的次数也+1
    7. 倘若temp等于k 说明所有组中的数字都已经出现在了滑动窗口中
    8. 此时倘若滑动窗口左侧对应的某一组的数字出现了不止1次,那么左侧窗口右移动,这样就是缩小区间,
    9. 同时计算最小的区间,记录在res当中
  • 提交结果在这里插入图片描述

633. 平方数之和

给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c 。

在这里插入图片描述

  • 解答

    //方法1
    public boolean judgeSquareSum(int c) {
            for (long a = 0; a * a <= c; a++) {
                double b = Math.sqrt(c - a * a);
                if (b == (int) b)
                    return true;
            }
            return false;
        }
    
    //方法2
    public boolean judgeSquareSum(int c) {
            int left = 0;
            int right = (int) Math.floor(Math.sqrt(c));
            while(left <= right) {
                int temp = left * left +  right * right;
                if(temp > c) {
                    right--;
                }else if(temp < c) {
                    left++;
                }else {
                    break;
                }
            }
            if(left <= right) {
                return true;
            }else {
                return false;
            }
        }
    
  • 分析

    1. 方法1
    2. 假设a的平方和是其中之一,那么另一个数字的平方和就是 c - a*a
    3. 若c - a * a 的开方是一个整数,那么就返回true
    4. 方法2
    5. 双指针法
  • 提交结果

    方法1在这里插入图片描述

    方法2在这里插入图片描述

636. 函数的独占时间

给出一个非抢占单线程CPU的 n 个函数运行日志,找到函数的独占时间。

每个函数都有一个唯一的 Id,从 0 到 n-1,函数可能会递归调用或者被其他函数调用。

日志是具有以下格式的字符串:function_id:start_or_end:timestamp。例如:“0:start:0” 表示函数 0 从 0 时刻开始运行。“0🔚0” 表示函数 0 在 0 时刻结束。

函数的独占时间定义是在该方法中花费的时间,调用其他函数花费的时间不算该函数的独占时间。你需要根据函数的 Id 有序地返回每个函数的独占时间。

在这里插入图片描述

  • 解答

    public int[] exclusiveTime(int n, List<String> logs) {
            int[] res = new int[n];
            Stack<String> stack = new Stack<>();
            int lastTime = 0;
            for(int i = 0;i < logs.size();i++){
                String curLog = logs.get(i);
                String[] curLogStrs = curLog.split(":");
                if(stack.isEmpty()){
                    stack.push(curLog);
                    lastTime = Integer.valueOf(curLogStrs[2]);
                    continue;
                }
                if(curLogStrs[1].equals("end")){
                    String lastLog = stack.pop();
                    String[] lastLogStrs = lastLog.split(":");
                    res[Integer.valueOf(curLogStrs[0])] += Integer.valueOf(curLogStrs[2]) - lastTime + 1;
                }else{
                    String lastLog = stack.peek();
                    String[] lastLogStrs = lastLog.split(":");
                    res[Integer.valueOf(lastLogStrs[0])] += Integer.valueOf(curLogStrs[2]) - lastTime -1;
                    stack.push(curLog);
                }
                lastTime = Integer.valueOf(curLogStrs[2]);
            }
            return res;
        }
    
  • 分析

    1. 利用栈来模拟函数调用
    2. 当前栈空,记录下时间,入栈 继续遍历
    3. 当前日志表示结束 那么就取出栈顶元素,当前函数的id的运行时间 更新
    4. 当前日志表示开始,那么看栈顶的日志,得到栈顶函数的id,更新运行时间。
  • 提交结果在这里插入图片描述

637. 二叉树的层平均值

在这里插入图片描述

  • 解答

    public List<Double> averageOfLevels(TreeNode root) {
            List<Double> res = new ArrayList<>();
            List<TreeNode> list = new ArrayList<>();
            list.add(root);
            while(!list.isEmpty()){
                List<TreeNode> temp = new ArrayList<>();
                double sum = 0;
                int size = list.size();
                for(TreeNode node:list){
                    sum += node.val;
                    if(node.left!=null)temp.add(node.left);
                    if(node.right!=null)temp.add(node.right);
                }
                res.add(sum/size);
                list = temp;
            }
            return res;
        }
    
  • 分析

    1. 层次遍历,得到每层的和,然后求平均值。
  • 提交结果在这里插入图片描述

638. 大礼包

在LeetCode商店中, 有许多在售的物品。

然而,也有一些大礼包,每个大礼包以优惠的价格捆绑销售一组物品。

现给定每个物品的价格,每个大礼包包含物品的清单,以及待购物品清单。请输出确切完成待购清单的最低花费。

每个大礼包的由一个数组中的一组数据描述,最后一个数字代表大礼包的价格,其他数字分别表示内含的其他种类物品的数量。

任意大礼包可无限次购买。

在这里插入图片描述

  • 解答

    int min = Integer.MAX_VALUE;
        public int shoppingOffers(List<Integer> price, List<List<Integer>> special, List<Integer> needs) {
            dfs(price,special,needs,0,0);
            return min;
        }
        public void dfs(List<Integer> price, List<List<Integer>> special, List<Integer> needs,int needMoney,int index){
            for(int j = index;j < special.size();j++){
                List<Integer> list = special.get(j);
                List<Integer> remain = new ArrayList<>();
                for(int i = 0;i < list.size()-1;i++){
                    if(list.get(i) > needs.get(i))break;
                    remain.add(needs.get(i) - list.get(i) >=0 ? needs.get(i) - list.get(i) : 0);
                }
                if(remain.size() == needs.size())
                    dfs(price,special,remain,needMoney + list.get(list.size()-1),j);
            }
            for(int i = 0;i < price.size();i++){
                needMoney += needs.get(i) * price.get(i);
            }
            min = Math.min(min,needMoney);
        }
    
  • 分析

    1. 递归回溯实现
    2. dfs中第一个for循环 判断能否使用大礼包,若可以 则购买大礼包,递归
    3. 第二个for循环是当剩余的部分无法满足大礼包的条件,那么久逐个购买。
    4. 最后留下花费较少的答案。
  • 提交结果在这里插入图片描述

639. 解码方法 2

一条包含字母 A-Z 的消息通过以下的方式进行了编码:

在这里插入图片描述

除了上述的条件以外,现在加密字符串可以包含字符 '‘了,字符’'可以被当做1到9当中的任意一个数字。

给定一条包含数字和字符’*'的加密信息,请确定解码方法的总数。

同时,由于结果值可能会相当的大,所以你应当对109 + 7取模。(翻译者标注:此处取模主要是为了防止溢出)

在这里插入图片描述

  • 解答

    public int numDecodings(String s) {
            int M = 1000000007;
            long[] dp = new long[s.length() + 1];
            dp[0] = 1;
            dp[1] = s.charAt(0) == '*' ? 9 : s.charAt(0) == '0' ? 0 : 1;
            for (int i = 1; i < s.length(); i++) {
                if (s.charAt(i) == '*') {
                    dp[i + 1] = 9 * dp[i];
                    if (s.charAt(i - 1) == '1')
                        dp[i + 1] = (dp[i + 1] + 9 * dp[i - 1]) % M;
                    else if (s.charAt(i - 1) == '2')
                        dp[i + 1] = (dp[i + 1] + 6 * dp[i - 1]) % M;
                    else if (s.charAt(i - 1) == '*')
                        dp[i + 1] = (dp[i + 1] + 15 * dp[i - 1]) % M;
                } else {
                    dp[i + 1] = s.charAt(i) != '0' ? dp[i] : 0;
                    if (s.charAt(i - 1) == '1')
                        dp[i + 1] = (dp[i + 1] + dp[i - 1]) % M;
                    else if (s.charAt(i - 1) == '2' && s.charAt(i) <= '6')
                        dp[i + 1] = (dp[i + 1] + dp[i - 1]) % M;
                    else if (s.charAt(i - 1) == '*')
                        dp[i + 1] = (dp[i + 1] + (s.charAt(i) <= '6' ? 2 : 1) * dp[i - 1]) % M;
                }
            }
            return (int) dp[s.length()];
        }
    
  • 分析

    1. 动态规划

    2. 当前数字和前面得到的结果是有关联的。

    3. 初始条件dp[0] = 1,dp[1] = s.charAt(0) == ‘*’ ? 9 : s.charAt(0) == ‘0’ ? 0 : 1

    4. 从下标1开始遍历

    5. 若当前字符是"*" 那么dp[i + 1] = dp[i] * 9

      若前一位是1 那么还要加上dp[i-1] * 9 表示 前i-1个字符 和后面两位字符 “1*” 的组合数

      若前一位是2 那么还要加上dp[i-1] * 6 表示 前i-1个字符 和后面两位字符 “2*” 的组合数

      若前一位是* 那么还要加上dp[i-1] * 15 表示 前i-1ge字符和后面两位字符 “**” 的组合数

    6. 若当前字符不是"*" 那么dp[i + 1] = s.charAt(i) != ‘0’ ? dp[i] : 0; 取决于当前字符是否是0

      若前一位是1。那么还要加上dp[i-1] 表示 前i- 1个字符 和后面两位字符 "1x"的组合数

      若前一位是2 并且当前位小于等于6 那么还要加上dp[i-1] 表示 前i-1个字符和后面两位 字符"2x"的组合数

      若前一位是* 那么dp[i + 1] = (dp[i + 1] + (s.charAt(i) <= ‘6’ ? 2 : 1) * dp[i - 1]) % M;

    7. 最后返回dp数组中的最后一个数字

  • 提交结果在这里插入图片描述

640. 求解方程

求解一个给定的方程,将x以字符串"x=#value"的形式返回。该方程仅包含’+’,’ - '操作,变量 x 和其对应系数。

如果方程没有解,请返回“No solution”。

如果方程有无限解,则返回“Infinite solutions”。

如果方程中只有一个解,要保证返回值 x 是一个整数。

在这里插入图片描述

  • 解答

    public String solveEquation(String equation) {
            String[] strs = equation.split("=");
            int leftNumber = 0,rightNumber = 0,leftXNumber = 0,rightXNumber = 0;
            int num = 0;
            int flag = 0;
            int j = 0;
            for(int i = 0;i < strs[0].length();i++){
                char cur = strs[0].charAt(i);
                if(cur >= '0' && cur <= '9'){
                    num = num * 10 + (cur - '0');
                }else if(cur == 'x'){
                    if(num == 0){
                        if(i - 1 >= 0 && strs[0].charAt(i-1) == '0')continue;
                        num++;
                    }
                    flag = 1;
                }else if(cur == '+' || cur == '-'){
                    if(j == 0){
                        if(flag == 1)leftXNumber += num;
                        else leftNumber += num;
                    }else{
                        if(flag == 1)leftXNumber -= num;
                        else leftNumber -= num;
                    }
                    flag = 0;
                    num = 0;
                    j = cur == '+' ? 0 : 1;
                }
            }
            if(j == 0){
                if(flag == 1)leftXNumber += num;
                else leftNumber += num;
            }else{
                if(flag == 1)leftXNumber -= num;
                else leftNumber -= num;
            }
    
            num = 0;
            flag = 0;
            j = 0;
            for(int i = 0;i < strs[1].length();i++){
                char cur = strs[1].charAt(i);
                if(cur >= '0' && cur <= '9'){
                    num = num * 10 + (cur - '0');
                }else if(cur == 'x'){
                    if(num == 0){
                        if(i - 1 >= 0 && strs[1].charAt(i-1) == '0')continue;
                        num++;
                    }
                    flag = 1;
                }else if(cur == '+' || cur == '-'){
                    if(j == 0){
                        if(flag == 1)rightXNumber += num;
                        else rightNumber += num;
                    }else{
                        if(flag == 1)rightXNumber -= num;
                        else rightNumber -= num;
                    }
                    num = 0;
                    flag = 0;
                    j = cur == '+' ? 0 : 1;
                }
            }
            if(j == 0){
                if(flag == 1)rightXNumber += num;
                else rightNumber += num;
            }else{
                if(flag == 1)rightXNumber -= num;
                else rightNumber -= num;
            }
    
            int XNumber = leftXNumber - rightXNumber;
            int Number = rightNumber - leftNumber;
            if(XNumber == 0 && Number != 0)return "No solution";
            else if(XNumber == 0 && Number == 0)return "Infinite solutions";
            else if(XNumber != 0 && Number == 0)return "x=0";
            else return "x=" + (Number / XNumber);
        }
    
  • 分析

    1. 将等式分成左右两边
    2. 分别统计左边的x的数量和纯数字 以及右边的x的数量和纯数字
    3. 然后就可以求x了
    4. 注意"0x"的情况,所以加了这一行代码 if(i - 1 >= 0 && strs[1].charAt(i-1) == ‘0’)continue;
  • 提交结果在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值