2022-6-13 咒语和药水的成功对数,替换字符后匹配,统计得分小于 K 的子数组数目,......

1. 咒语和药水的成功对数

You are given two positive integer arrays spells and potions, of length n and m respectively, where spells[i] represents the strength of the ith spell and potions[j] represents the strength of the jth potion.

You are also given an integer success. A spell and potion pair is considered successful if the product of their strengths is at least success.

Return an integer array pairs of length n where pairs[i] is the number of potions that will form a successful pair with the ith spell.

Example 1

Input: spells = [5,1,3], potions = [1,2,3,4,5], success = 7
Output: [4,0,3]
Explanation:
- 0th spell: 5 * [1,2,3,4,5] = [5,10,15,20,25]. 4 pairs are successful.
- 1st spell: 1 * [1,2,3,4,5] = [1,2,3,4,5]. 0 pairs are successful.
- 2nd spell: 3 * [1,2,3,4,5] = [3,6,9,12,15]. 3 pairs are successful.
Thus, [4,0,3] is returned.

Example 2

Input: spells = [3,1,2], potions = [8,5,8], success = 16
Output: [2,0,2]
Explanation:
- 0th spell: 3 * [8,5,8] = [24,15,24]. 2 pairs are successful.
- 1st spell: 1 * [8,5,8] = [8,5,8]. 0 pairs are successful. 
- 2nd spell: 2 * [8,5,8] = [16,10,16]. 2 pairs are successful. 
Thus, [2,0,2] is returned.

Constraints:

  • n == spells.length
  • m == potions.length
  • 1 <= n, m <= 10^5
  • 1 <= spells[i], potions[i] <= 10^5
  • 1 <= success <= 10^10

代码 [二分]

class Solution {
public:
    vector<int> successfulPairs(vector<int> &spells, vector<int> &potions, long long success) {
        sort(potions.begin(), potions.end());
        vector<int> result(spells.size());
        for (int i = 0; i < spells.size(); ++i) {
            int lo = min(100001ll, (success - 1) / spells[i] + 1);
            result[i] = potions.end() - lower_bound(potions.begin(), potions.end(), lo);
        }
        return result;
    }
};

2. 替换字符后匹配

You are given two strings s and sub. You are also given a 2D character array mappings where mappings[i] = [oldi, newi] indicates that you may replace any number of oldi characters of sub with newi. Each character in sub cannot be replaced more than once.

Return true if it is possible to make sub a substring of s by replacing zero or more characters according to mappings. Otherwise, return false.

A substring is a contiguous non-empty sequence of characters within a string.

Example 1

Input: s = "fool3e7bar", sub = "leet", mappings = [["e","3"],["t","7"],["t","8"]]
Output: true
Explanation: Replace the first 'e' in sub with '3' and 't' in sub with '7'.
Now sub = "l3e7" is a substring of s, so we return true.

Example 2

Input: s = "fooleetbar", sub = "f00l", mappings = [["o","0"]]
Output: false
Explanation: The string "f00l" is not a substring of s and no replacements can be made.
Note that we cannot replace '0' with 'o'.

Constraints:

  • 1 <= sub.length <= s.length <= 5000
  • 0 <= mappings.length <= 1000
  • mappings[i].length == 2
  • oldi != newi
  • s and sub consist of uppercase and lowercase English letters and digits.
  • oldi and newi are either uppercase or lowercase English letters or digits.

代码 [0x3f,哈希]

class Solution:
    def matchReplacement(self, s: str, sub: str, mappings: List[List[str]]) -> bool:
        mp = set((x, y) for x, y in mappings)
        for i in range(len(sub), len(s) + 1):
            if all(x == y or (x, y) in mp for x, y in zip(sub, s[i - len(sub):i])):
                return True
        return False

3. 统计得分小于 K 的子数组数目

The score of an array is defined as the product of its sum and its length.

  • For example, the score of [1, 2, 3, 4, 5] is (1 + 2 + 3 + 4 + 5) * 5 = 75.

Given a positive integer array nums and an integer k, return the number of non-empty subarrays of nums whose score is strictly less than k.

A subarray is a contiguous sequence of elements within an array.

Example 1

Input: nums = [2,1,4,3,5], k = 10
Output: 6
Explanation:
The 6 subarrays having scores less than 10 are:
- [2] with score 2 * 1 = 2.
- [1] with score 1 * 1 = 1.
- [4] with score 4 * 1 = 4.
- [3] with score 3 * 1 = 3. 
- [5] with score 5 * 1 = 5.
- [2,1] with score (2 + 1) * 2 = 6.
Note that subarrays such as [1,4] and [4,3,5] are not considered because their scores are 10 and 36 respectively, while we need scores strictly less than 10.

Example 2

Input: nums = [1,1,1], k = 5
Output: 5
Explanation:
Every subarray except [1,1,1] has a score less than 5.
[1,1,1] has a score (1 + 1 + 1) * 3 = 9, which is greater than 5.
Thus, there are 5 subarrays having scores less than 5.

Constraints:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^5
  • 1 <= k <= 10^15

代码 [滑动窗口]

class Solution:
    def countSubarrays(self, nums: List[int], k: int) -> int:
        ans = s = lo = 0
        for hi, num in enumerate(nums):
            s += num
            while s * (hi - lo + 1) >= k:
                s -= nums[lo]
                lo += 1
            ans += hi - lo + 1
        return ans

4. 划分数组使最大差为 K

You are given an integer array nums and an integer k. You may partition nums into one or more subsequences such that each element in nums appears in exactly one of the subsequences.

Return the minimum number of subsequences needed such that the difference between the maximum and minimum values in each subsequence is at most k.

A subsequence is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements.

Example 1

Input: nums = [3,6,1,2,5], k = 2
Output: 2
Explanation:
We can partition nums into the two subsequences [3,1,2] and [6,5].
The difference between the maximum and minimum value in the first subsequence is 3 - 1 = 2.
The difference between the maximum and minimum value in the second subsequence is 6 - 5 = 1.
Since two subsequences were created, we return 2. It can be shown that 2 is the minimum number of subsequences needed.

Example 2

Input: nums = [1,2,3], k = 1
Output: 2
Explanation:
We can partition nums into the two subsequences [1,2] and [3].
The difference between the maximum and minimum value in the first subsequence is 2 - 1 = 1.
The difference between the maximum and minimum value in the second subsequence is 3 - 3 = 0.
Since two subsequences were created, we return 2. Note that another optimal solution is to partition nums into the two subsequences [1] and [2,3].

Constraints:

  • 1 <= nums.length <= 10^5
  • 0 <= nums[i] <= 10^5
  • 0 <= k <= 10^5

代码 [滑动窗口/二分]

class Solution {
public:
    int partitionArray(vector<int> nums, int k) {
        int result = 0;
        sort(nums.begin(), nums.end());
        for (int lo = 0, hi, up; lo < nums.size(); lo = hi) {
            hi = nums.size(), up = nums[lo] + k, result++;
            while (lo < hi) {
                int mi = lo + ((hi - lo) >> 1);
                nums[mi] <= up ? lo = mi + 1 : hi = mi;
            }
        }
        return result;
    }
};

5. 替换数组中的元素

给你一个下标从 0 开始的数组 nums ,它包含 n互不相同 的正整数。请你对这个数组执行 m 个操作,在第 i 个操作中,你需要将数字 operations[i][0] 替换成 operations[i][1]

题目保证在第 i 个操作中:

  • operations[i][0]nums 中存在。
  • operations[i][1]nums 中不存在。

请你返回执行完所有操作后的数组。

Example 1

输入:nums = [1,2,4,6], operations = [[1,3],[4,7],[6,1]]
输出:[3,2,7,1]
解释:我们对 nums 执行以下操作:
- 将数字 1 替换为 3 。nums 变为 [3,2,4,6] 。
- 将数字 4 替换为 7 。nums 变为 [3,2,7,6] 。
- 将数字 6 替换为 1 。nums 变为 [3,2,7,1] 。
返回最终数组 [3,2,7,1] 。

Example 2

输入:nums = [1,2], operations = [[1,3],[2,1],[3,2]]
输出:[2,1]
解释:我们对 nums 执行以下操作:
- 将数字 1 替换为 3 。nums 变为 [3,2] 。
- 将数字 2 替换为 1 。nums 变为 [3,1] 。
- 将数字 3 替换为 2 。nums 变为 [2,1] 。
返回最终数组 [2,1] 。

Constraints:

  • n == nums.length
  • m == operations.length
  • 1 <= n, m <= 10^5
  • All the values of nums are distinct.
  • operations[i].length == 2
  • 1 <= nums[i], operations[i][0], operations[i][1] <= 10^6
  • operations[i][0] will exist in nums when applying the ith operation.
  • operations[i][1] will not exist in nums when applying the ith operation.

代码 [模拟]

class Solution:
    def arrayChange(self, nums: List[int], operations: List[List[int]]) -> List[int]:
        idx = {num: i for i, num in enumerate(nums)}
        for x, y in operations:
            i = idx[x]
            nums[i] = y
            del idx[x]
            idx[y] = i
        return nums

6. 设计一个文本编辑器

Design a text editor with a cursor that can do the following:

  • Add text to where the cursor is.
  • Delete text from where the cursor is (simulating the backspace key).
  • Move the cursor either left or right.

When deleting text, only characters to the left of the cursor will be deleted. The cursor will also remain within the actual text and cannot be moved beyond it. More formally, we have that 0 <= cursor.position <= currentText.length always holds.

Implement the TextEditor class:

  • TextEditor() Initializes the object with empty text.
  • void addText(string text) Appends text to where the cursor is. The cursor ends to the right of text.
  • int deleteText(int k) Deletes k characters to the left of the cursor. Returns the number of characters actually deleted.
  • string cursorLeft(int k) Moves the cursor to the left k times. Returns the last min(10, len) characters to the left of the cursor, where len is the number of characters to the left of the cursor.
  • string cursorRight(int k) Moves the cursor to the right k times. Returns the last min(10, len) characters to the left of the cursor, where len is the number of characters to the left of the cursor.

Example 1

Input
["TextEditor", "addText", "deleteText", "addText", "cursorRight", "cursorLeft", "deleteText", "cursorLeft", "cursorRight"]
[[], ["leetcode"], [4], ["practice"], [3], [8], [10], [2], [6]]
Output
[null, null, 4, null, "etpractice", "leet", 4, "", "practi"]

Explanation
TextEditor textEditor = new TextEditor(); // The current text is "|". (The '|' character represents the cursor)
textEditor.addText("leetcode"); // The current text is "leetcode|".
textEditor.deleteText(4); // return 4
                          // The current text is "leet|". 
                          // 4 characters were deleted.
textEditor.addText("practice"); // The current text is "leetpractice|". 
textEditor.cursorRight(3); // return "etpractice"
                           // The current text is "leetpractice|". 
                           // The cursor cannot be moved beyond the actual text and thus did not move.
                           // "etpractice" is the last 10 characters to the left of the cursor.
textEditor.cursorLeft(8); // return "leet"
                          // The current text is "leet|practice".
                          // "leet" is the last min(10, 4) = 4 characters to the left of the cursor.
textEditor.deleteText(10); // return 4
                           // The current text is "|practice".
                           // Only 4 characters were deleted.
textEditor.cursorLeft(2); // return ""
                          // The current text is "|practice".
                          // The cursor cannot be moved beyond the actual text and thus did not move. 
                          // "" is the last min(10, 0) = 0 characters to the left of the cursor.
textEditor.cursorRight(6); // return "practi"
                           // The current text is "practi|ce".
                           // "practi" is the last min(10, 6) = 6 characters to the left of the cursor.

Constraints:

  • 1 <= text.length, k <= 40
  • text consists of lowercase English letters.
  • At most 2 * 10^4 calls in total will be made to addText, deleteText, cursorLeft and cursorRight.

代码 [双向链表]

struct Node {
    char val;
    Node *prev, *next;
    Node(char val = 0) : val(val), prev(nullptr), next(nullptr) {}
    Node(char val, Node *prev, Node *next) : val(val), prev(prev), next(next) {}
};

class TextEditor {
private:
    Node *dummyHead, *dummyTail, *curNode;

    inline void insertBefore(char val) {
        auto node = new Node(val, curNode->prev, curNode);
        curNode->prev->next = node;
        curNode->prev = node;
    }

    inline bool deleteBefore() {
        if (curNode->prev == dummyHead) return false;
        curNode->prev = curNode->prev->prev;
        curNode->prev->next = curNode;
        return true;
    }

    string readBefore(int n = 10) {
        auto node = curNode;
        while (n-- && node->prev != dummyHead)
            node = node->prev;
        string s;
        while (node != curNode) {
            s.push_back(node->val);
            node = node->next;
        }
        return s;
    }

public:
    TextEditor() {
        dummyHead = new Node();
        dummyTail = new Node();
        dummyHead->next = dummyTail;
        dummyTail->prev = dummyHead;
        curNode = dummyTail;
    }

    void addText(string text) { for (char ch:text) insertBefore(ch); }

    int deleteText(int k) {
        for (int i = 0; i < k; i++) { if (!deleteBefore()) return i; }
        return k;
    }

    string cursorLeft(int k) {
        while (k-- && curNode->prev != dummyHead) curNode = curNode->prev;
        return move(readBefore());
    }

    string cursorRight(int k) {
        while (k-- && curNode->next != nullptr) curNode = curNode->next;
        return move(readBefore());
    }
};

7. 排字符形成目标字符串

给你两个下标从 0 开始的字符串 starget 。你可以从 s 取出一些字符并将其重排,得到若干新的字符串。

s 中取出字符并重新排列,返回可以形成 target最大 副本数。

Example 1

输入:s = "ilovecodingonleetcode", target = "code"
输出:2
解释:
对于 "code" 的第 1 个副本,选取下标为 4 、5 、6 和 7 的字符。
对于 "code" 的第 2 个副本,选取下标为 17 、18 、19 和 20 的字符。
形成的字符串分别是 "ecod" 和 "code" ,都可以重排为 "code" 。
可以形成最多 2 个 "code" 的副本,所以返回 2 。

提示:

  • 1 <= s.length <= 100
  • 1 <= target.length <= 10
  • starget 由小写英文字母组成

代码 [哈希]

class Solution {
public:
    int rearrangeCharacters(const string &s, const string &target) {
        unordered_map<char, int> mpTarget; // 由于 s 和 target 由小写字母组成, 因此使用数组做哈希更合适一些
        for (char ch:target) mpTarget[ch]++;
        unordered_map<char, int> mpSource;
        for (char ch:s) {
            if (mpTarget.count(ch)) mpSource[ch]++;
        }
        int result = INT_MAX;
        for (char ch:target) {
            result = min(mpSource[ch] / mpTarget[ch], result);
        }
        return result;
    }
};

8. 价格减免

A sentence is a string of single-space separated words where each word can contain digits, lowercase letters, and the dollar sign '$'. A word represents a price if it is a sequence of digits preceded by a dollar sign.

  • For example, "$100", "$23", and "$6" represent prices while "100", "$", and "$1e5" do not.

You are given a string sentence representing a sentence and an integer discount. For each word representing a price, apply a discount of discount% on the price and update the word in the sentence. All updated prices should be represented with exactly two decimal places.

Return a string representing the modified sentence.

Note that all prices will contain at most 10 digits.

Example 1

Input: sentence = "there are $1 $2 and 5$ candies in the shop", discount = 50
Output: "there are $0.50 $1.00 and 5$ candies in the shop"
Explanation: 
The words which represent prices are "$1" and "$2". 
- A 50% discount on "$1" yields "$0.50", so "$1" is replaced by "$0.50".
- A 50% discount on "$2" yields "$1". Since we need to have exactly 2 decimal places after a price, we replace "$2" with "$1.00".

Constraints:

  • 1 <= sentence.length <= 10^5
  • sentence consists of lowercase English letters, digits, ' ', and '$'.
  • sentence does not have leading or trailing spaces.
  • All words in sentence are separated by a single space.
  • All prices will be positive integers without leading zeros.
  • All prices will have at most 10 digits.
  • 0 <= discount <= 100

代码

class Solution:
    def discountPrices(self, sentence: str, discount: int) -> str:
        words = sentence.split(' ')
        for i, word in enumerate(words):
            if word[0] == '$' and word[1:].isdigit():
                ct = eval(word[1:]) * (100.0 - discount) / 100.0
                words[i] = f'${ct:.2f}'
        return ' '.join(words)

9. 计算右侧小于当前元素的个数 [逆序对数]

给你一个整数数组 nums ,按要求返回一个新数组 counts 。数组 counts 有该性质: counts[i] 的值是 nums[i] 右侧小于 nums[i] 的元素的数量。

Example 1

输入:nums = [5,2,6,1]
输出:[2,1,1,0] 
解释:
5 的右侧有 2 个更小的元素 (2 和 1)
2 的右侧仅有 1 个更小的元素 (1)
6 的右侧有 1 个更小的元素 (1)
1 的右侧有 0 个更小的元素

提示:

  • 1 <= nums.length <= 105
  • -104 <= nums[i] <= 104

代码 [线段树]

class Solution {
private:
    vector<int> segTree;

    void build(unsigned int n) {
        segTree.assign(n << 2, 0);
    }

    void insert(int start, int end, int node, int val) {
        segTree[node]++;
        if (start == end) return;
        int mid = start + ((end - start) >> 1);
        int left_node = (node << 1) + 1, right_node = (node << 1) + 2;
        val <= mid ? insert(start, mid, left_node, val) : insert(mid + 1, end, right_node, val);
    }

    int query(int start, int end, int L, int R, int node) {
        if (start > R || end < L) return 0;
        if (L <= start && end <= R) return segTree[node];
        int mid = start + ((end - start) >> 1);
        int left_node = (node << 1) + 1, right_node = (node << 1) + 2;
        return query(start, mid, L, R, left_node) + query(mid + 1, end, L, R, right_node);
    }

public:
    vector<int> countSmaller(const vector<int> &nums) {
        vector<int> tmp(nums.begin(), nums.end());
        sort(tmp.begin(), tmp.end());
        tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
        build(tmp.size());
        unordered_map<int, int> mp;
        for (int i = 0; i < tmp.size(); ++i) mp[tmp[i]] = i;
        vector<int> result(nums.size());
        for (int i = nums.size() - 1; i >= 0; --i) {
            int idx = mp[nums[i]];
            result[i] = query(0, mp.size() - 1, 0, idx - 1, 0);
            insert(0, mp.size() - 1, 0, idx);
        }
        return result;
    }
};

10. 数组中的逆序对 [逆序对数]

在数组中的两个数字,如果前面一个数字大于后面的数字,则这两个数字组成一个逆序对。输入一个数组,求出这个数组中的逆序对的总数。

Example 1

输入: [7,5,6,4]
输出: 5

提示:

  • 0 <= 数组长度 <= 50000

代码 [线段树]

class Solution {
private:
    vector<int> segTree;

    void build(unsigned int n) {
        segTree.assign(n << 2, 0);
    }

    void insert(int start, int end, int node, int val) {
        segTree[node]++;
        if (start == end) return;
        int mid = start + ((end - start) >> 1);
        int left_node = (node << 1) + 1, right_node = (node << 1) + 2;
        val <= mid ? insert(start, mid, left_node, val) : insert(mid + 1, end, right_node, val);
    }

    int query(int start, int end, int L, int R, int node) {
        if (start > R || end < L) return 0;
        if (L <= start && end <= R) return segTree[node];
        int mid = start + ((end - start) >> 1);
        int left_node = (node << 1) + 1, right_node = (node << 1) + 2;
        return query(start, mid, L, R, left_node) + query(mid + 1, end, L, R, right_node);
    }

public:
    int reversePairs(const vector<int> &nums) {
        vector<int> tmp(nums.begin(), nums.end());
        sort(tmp.begin(), tmp.end());
        tmp.erase(unique(tmp.begin(), tmp.end()), tmp.end());
        build(tmp.size());
        unordered_map<int, int> mp;
        for (int i = 0; i < tmp.size(); ++i) mp[tmp[i]] = i;
        int result = 0;
        for (int i = nums.size() - 1; i >= 0; --i) {
            int idx = mp[nums[i]];
            result += query(0, mp.size() - 1, 0, idx - 1, 0);
            insert(0, mp.size() - 1, 0, idx);
        }
        return result;
    }
};

11. 使数组按非递减顺序排列

给你一个下标从 0 开始的整数数组 nums 。在一步操作中,移除所有满足 nums[i - 1] > nums[i]nums[i] ,其中 0 < i < nums.length

重复执行步骤,直到 nums 变为 非递减 数组,返回所需执行的操作数。

Example 1

输入:nums = [5,3,4,4,7,3,6,11,8,5,11]
输出:3
解释:执行下述几个步骤:
- 步骤 1 :[5,3,4,4,7,3,6,11,8,5,11] 变为 [5,4,4,7,6,11,11]
- 步骤 2 :[5,4,4,7,6,11,11] 变为 [5,4,7,11,11]
- 步骤 3 :[5,4,7,11,11] 变为 [5,7,11,11]
[5,7,11,11] 是一个非递减数组,因此,返回 3 。

提示:

  • 1 <= nums.length <= 10^5
  • 1 <= nums[i] <= 10^9

代码 [0x3f视频讲解,单调栈]

class Solution {
public:
    int totalSteps(vector<int> &nums) {
        int ans = 0;
        stack<pair<int, int>> st;
        for (int num : nums) {
            int maxT = 0;
            while (!st.empty() && st.top().first <= num) {
                maxT = max(maxT, st.top().second);
                st.pop();
            } 
            maxT = st.empty() ? 0 : maxT + 1;
            ans = max(ans, maxT);
            st.emplace(num, maxT);
        }
        return ans;
    }
};

代码 [newhar,单调栈]

class Solution {
public:
    int totalSteps(vector<int> &nums) {
        stack<int> st;
        int res = 0, f[nums.size()];
        for (int i = 0; i < nums.size(); ++i) {
            int cur = 0;
            while (!st.empty() && nums[st.top()] <= nums[i]) {
                cur = max(cur, f[st.top()]);
                st.pop();
            }
            if (!st.empty()) {
                res = max(res, cur + 1);
                f[i] = cur + 1;
            }
            st.push(i);
        }
        return res;
    }
};

12. 到达角落需要移除障碍物的最小数目

给你一个下标从 0 开始的二维整数数组 grid ,数组大小为 m x n 。每个单元格都是两个值之一:

  • 0 表示一个 单元格,
  • 1 表示一个可以移除的 障碍物

你可以向上、下、左、右移动,从一个空单元格移动到另一个空单元格。

现在你需要从左上角 (0, 0) 移动到右下角 (m - 1, n - 1) ,返回需要移除的障碍物的 最小 数目。

Example 1

输入:grid = [[0,1,1],[1,1,0],[1,1,0]]
输出:2
解释:可以移除位于 (0, 1) 和 (0, 2) 的障碍物来创建从 (0, 0) 到 (2, 2) 的路径。
可以证明我们至少需要移除两个障碍物,所以返回 2 。
注意,可能存在其他方式来移除 2 个障碍物,创建出可行的路径。

代码 [0x3f视频讲解,01BFS]

class Solution {
    static constexpr int dirs[4][2] = {{1,  0}, {-1, 0}, {0,  1}, {0,  -1}};

public:
    int minimumObstacles(vector<vector<int>> &grid) {
        int m = grid.size(), n = grid[0].size();
        int dis[m][n];
        memset(dis, 0x3f, sizeof(dis));
        dis[0][0] = 0;
        deque<pair<int, int>> q;
        q.emplace_front(0, 0);
        while (!q.empty()) {
            auto[x, y] = q.front();
            q.pop_front();
            for (auto &[dx, dy] : dirs) {
                int nx = x + dx, ny = y + dy;
                if (0 <= nx && nx < m && 0 <= ny && ny < n) {
                    int g = grid[nx][ny];
                    if (dis[x][y] + g < dis[nx][ny]) {
                        dis[nx][ny] = dis[x][y] + g;
                        g == 0 ? q.emplace_front(nx, ny) : q.emplace_back(nx, ny);
                    }
                }
            }
        }
        return dis[m - 1][n - 1];
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值