数据结构与算法之堆: LeetCode 347. 前K个高频元素 (Ts, Py, Go版)

LeetCode-347-前k个高频元素-中等(红黑树/堆/快排) 一 题目 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 二 前言 像这种topK问题(前k小/前k大/第k大/第k小)的题解都是套路,基本就是堆排序O(nlogk)、快速选择O(n)【最快】、二叉搜索树O(nlogk)。本题只是在这基础上的变形而已,要处理值和频率对应的问题,所以考虑以哈希表为底层的unordered_map来处理,然后在后面排序的过程中需要注意数据结构的变化。 三 题解 1.两个红黑树反着赋值。 思路:考虑到 阅读详情

前K个高频元素

  • https://leetcode.cn/problems/top-k-frequent-elements/

描述

  • 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

示例 1

输入: nums = [1,1,1,2,2,3], k = 2
输出: [1,2]

示例 2

输入: nums = [1], k = 1
输出: [1]

提示

  • 1 <= nums.length <= 10510^5105
  • k 的取值范围是 [1, 数组中不相同的元素的个数]
  • 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的

进阶

  • 你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。

Typescript 版算法实现


1 )使用堆排序
class MinHeap {
    heap: Record<string, any>[] = [];
    // 交换节点位置
    swap(i, j) {
        [this.heap[i], this.heap[j]] = [this.heap[j], this.heap[i]];
    }
    // 获得父节点
    getParentIndex(i) {
        return (i - 1) >> 1;
    }
    // 获取左子节点
    getLeftIndex(i) {
        return (i << 1) + 1; // 极客写法
    }
    // 获取右子节点
    getRightIndex(i) {
        return (i << 1) + 2;
    }
    // 向上移动
    shiftUp(index) {
        // 如果到了堆顶元素,index是0,则不要再上移了
        if(!index) return;
        const parentIndex = this.getParentIndex(index)
        if(this.heap[parentIndex]?.value > this.heap[index].value) {
            this.swap(parentIndex, index)
            this.shiftUp(parentIndex)
        }
    }
    // 下移
    shiftDown(index) {
        // 边界1:如果到了堆尾元素,则不要再下移了
        if(index >= this.heap.length - 1) return;
        const size = this.size();
        const leftIndex = this.getLeftIndex(index);
        const rightIndex = this.getRightIndex(index);
        if (leftIndex < size && this.heap[leftIndex]?.value < this.heap[index].value) {
            this.swap(leftIndex, index);
            this.shiftDown(leftIndex);
        }
        // 注意,这里的 this.heap[index].value 和上面重复,不能使用变量,因为上个if中存在 swap 和 shiftDown, 使用变量有可能出问题
        if (rightIndex < size && this.heap[rightIndex]?.value < this.heap[index].value) {
            this.swap(rightIndex, index);
            this.shiftDown(rightIndex);
        }
    }
    // 插入
    insert(value) {
        this.heap.push(value);
        this.shiftUp(this.heap.length - 1);
    }
    // 删除堆顶
    pop() {
        // pop()方法删除数组最后一个元素并返回,赋值给堆顶
        this.heap[0] = this.heap.pop();
        // 对堆顶重新排序
        this.shiftDown(0);
    }
    // 获取堆顶
    peak() {
        return this.heap[0];
    }
    // 获取堆的大小
    size() {
        return this.heap.length;
    }
}

function topKFrequent(nums: number[], k: number): number[] {
    const map = new Map();
    nums.forEach(n => {
        map.set(n, map.has(n)? map.get(n) + 1 : 1);
    })
    const h = new MinHeap();
    map.forEach((value, key) => {
        h.insert({value, key});
        // 保证堆的尺寸是k
        (h.size() > k) &&  h.pop();
    })
    return h.heap.map(a => a.key);
}
  • 这里改造了之前的 MinHeap 最小堆类
  • 原来是值比较,现在是对象的比较

2 )使用字典

function topKFrequent(nums: number[], k: number): number[] {
    const map = new Map();
    nums.forEach(n => {
        map.set(n, map.has(n)? map.get(n) + 1 : 1);
    })
    // console.log(map); // 这是一个map结构
    // console.log(Array.from(map)); // 将map转换为二维数组,[[值, 频率], [值, 频率]] 这是无序的

    // 对Array.from(map)产生的二维矩阵进行频率的排序
    const list = Array.from(map).sort((a,b) => b[1] - a[1])
    return list.slice(0, k).map(i => i[0]); // 返回按频率排序的前K个元素值
}
  • 统计每个元素出现的次数(频率)
  • 通过Map结构来处理
  • 分析时间复杂度:O(nlogn)
  • 一个forEach循环O(n)
  • 原生sort排序,O(nlogn)
  • 总体来说O(nlogn)
  • 如果题目要求,返回的前K个高频元素不考虑顺序,我们一下就要想到用堆排序

Python3 版算法实现


1 ) 方案1

class MinHeap:
    def __init__(self):
        self.heap = []

    def swap(self, i, j):
        self.heap[i], self.heap[j] = self.heap[j], self.heap[i]

    def get_parent_index(self, i):
        return (i - 1) // 2

    def get_left_index(self, i):
        return (i << 1) + 1

    def get_right_index(self, i):
        return (i << 1) + 2

    def shift_up(self, index):
        if index == 0:
            return
        parent_index = self.get_parent_index(index)
        if self.heap[parent_index]['value'] > self.heap[index]['value']:
            self.swap(parent_index, index)
            self.shift_up(parent_index)

    def shift_down(self, index):
        if index >= len(self.heap) - 1:
            return
        size = len(self.heap)
        left_index = self.get_left_index(index)
        right_index = self.get_right_index(index)
        if left_index < size and self.heap[left_index]['value'] < self.heap[index]['value']:
            self.swap(left_index, index)
            self.shift_down(left_index)
        if right_index < size and self.heap[right_index]['value'] < self.heap[index]['value']:
            self.swap(right_index, index)
            self.shift_down(right_index)

    def insert(self, value):
        self.heap.append(value)
        self.shift_up(len(self.heap) - 1)

    def pop(self):
        if len(self.heap) <= 1:
            return
        self.heap[0] = self.heap.pop()
        self.shift_down(0)

    def peak(self):
        return self.heap[0]

    def size(self):
        return len(self.heap)

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        from collections import Counter
        freq_map = Counter(nums)
        h = MinHeap()
        for key, value in freq_map.items():
            h.insert({'key': key, 'value': value})
            if h.size() > k:
                h.pop()
        return [item['key'] for item in h.heap]

2 )方案2

class Solution:
    def topKFrequent(self, nums: List[int], k: int) -> List[int]:
        from collections import Counter
        freq_map = Counter(nums)
        sorted_items = sorted(freq_map.items(), key=lambda x: x[1], reverse=True)
        return [item[0] for item in sorted_items[:k]]

Golang 版算法实现


1 ) 方案1

type MinHeap struct {
	heap []map[string]int
}

// 交换节点位置
func (h *MinHeap) swap(i, j int) {
	h.heap[i], h.heap[j] = h.heap[j], h.heap[i]
}

// 获得父节点
func (h *MinHeap) getParentIndex(i int) int {
	return (i - 1) >> 1
}

// 获取左子节点
func (h *MinHeap) getLeftIndex(i int) int {
	return (i << 1) + 1
}

// 获取右子节点
func (h *MinHeap) getRightIndex(i int) int {
	return (i << 1) + 2
}

// 向上移动
func (h *MinHeap) shiftUp(index int) {
	if index == 0 {
		return
	}
	parentIndex := h.getParentIndex(index)
	if h.heap[parentIndex]["value"] > h.heap[index]["value"] {
		h.swap(parentIndex, index)
		h.shiftUp(parentIndex)
	}
}

// 下移
func (h *MinHeap) shiftDown(index int) {
	if index >= len(h.heap)-1 {
		return
	}
	size := h.size()
	leftIndex := h.getLeftIndex(index)
	rightIndex := h.getRightIndex(index)
	if leftIndex < size && h.heap[leftIndex]["value"] < h.heap[index]["value"] {
		h.swap(leftIndex, index)
		h.shiftDown(leftIndex)
	}
	if rightIndex < size && h.heap[rightIndex]["value"] < h.heap[index]["value"] {
		h.swap(rightIndex, index)
		h.shiftDown(rightIndex)
	}
}

// 插入
func (h *MinHeap) insert(value map[string]int) {
	h.heap = append(h.heap, value)
	h.shiftUp(len(h.heap) - 1)
}

// 删除堆顶
func (h *MinHeap) pop() {
	if len(h.heap) <= 1 {
		return
	}
	h.heap[0] = h.heap[len(h.heap)-1]
	h.heap = h.heap[:len(h.heap)-1]
	h.shiftDown(0)
}

// 获取堆顶
func (h *MinHeap) peak() map[string]int {
	return h.heap[0]
}

// 获取堆的大小
func (h *MinHeap) size() int {
	return len(h.heap)
}

func topKFrequent(nums []int, k int) []int {
	freqMap := make(map[int]int)
	for _, n := range nums {
		freqMap[n]++
	}

	h := &MinHeap{}
	for key, value := range freqMap {
		h.insert(map[string]int{"key": key, "value": value})
		if h.size() > k {
			h.pop()
		}
	}

	result := make([]int, k)
	for i, item := range h.heap {
		result[i] = item["key"]
	}
	return result
}

2 )方案2

func topKFrequent(nums []int, k int) []int {
	freqMap := make(map[int]int)
	for _, n := range nums {
		freqMap[n]++
	}

	type kv struct {
		Key   int
		Value int
	}
	var list []kv
	for k, v := range freqMap {
		list = append(list, kv{k, v})
	}

	sort.Slice(list, func(i, j int) bool {
		return list[i].Value > list[j].Value
	})

	result := make([]int, k)
	for i := 0; i < k; i++ {
		result[i] = list[i].Key
	}
	return result
}
LeetCode刷题日记之前K个高频元素 前K个高频元素,这是一个很有代表性的问题,在实际生活中的应用场景其实也很多,比如微博里每天统计实时热点信息等。 先看下题: 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 进阶:你所设计算法的时间复杂度 必须 优于 O(n log n) ,其中 n 是数组大小。 这道题的进阶要求时间复杂度要优于O(nlogn),那一般的快排,归并等就可以抛弃 阅读详情

相关推荐

论文阅读《Eigen-GNN: A Graph Structure Preserving Plug-in for GNNs》

好久没看论文了,感觉好生疏 关于这篇文章的大致脉络,这篇文章已经介绍过了。

且视他人之疑目如盏盏鬼火,大胆地去走你的夜路 462

leetcode 347:前K个高频元素

leetcode 347:前K个高频元素 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] 提示: 1 <= nums.length <= 105 k 的取值范围是 [1, 数组中不相同的元素的个数] 题目数据保证答

yingmu__的博客 920

新手3dslicer手动肝脏切割及体积测量(详细图文)

刚接手软件的时候,我一直想用自动分割工具,试验了Med sam,依赖安装不了;试验了英伟达的AI,NvidiaAIAssis,传服务器根本没反应,所有只有用了手动切割。不要求所有层面勾画,但是最好是典型层面都勾画一下,特别是有毗邻脏器密度相近的层面。点击3D后可能三维窗口未显示,可以调整一下窗口大小,有可能显示在我们看见的范围之外。早就准备更新这篇了,由于懒癌发作,一直早葛优躺,今天刚好有点时间,就简单写下来。

linjianping513的博客 5932

LeetCode_排序_中等_347.前 K 个高频元素

目录1.题目2.思路3.代码实现(Java) 1.题目 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按任意顺序返回答案。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] 提示: 1 <= nums.length <= 105 k 的取值范围是 [1, 数组中不相同的元素的个数] 题目数据保证答案唯一,换句话说,数组中前 k 个高频元

代码星辰的博客 925

告别“静态组件”:Adobe XD的堆栈+状态,打造“活”的响应式UI

今天,我想分享一套能彻底告别这种“笨方法”的、Adobe XD中的进阶技巧,通过组合使用“堆栈”、“内边距”和“组件状态”,去构建一个能自动适应内容、真正“活”起来的智能响应式组件。

Kingsdesigner的博客 764

STM32CubeMX、keil、simulink联合开发MCU教程

一、整体思路 利用Matlab的simulink搭建模型生成C代码,通过stm32cubemx生成工程,最后在KEIL或者IAR等工具里面编译生成代码下载至MCU中执行。 本文以流水灯建立模型和简单使用定时器为例进行演示。 二、开发环境 1、安装Matlab Matlab版本建议在2013B以上,本文使用Matlab 2016a。 2、安装STM32硬件支持包 下载地址(https://www.stmcu.org.cn/document/detail/index/id-216053) 安装完成后重启MAT

tzlaa的博客 7742

leetcode刷题/栈和队列 347. 前 K 个高频元素

347. 前 K 个高频元素 题意: 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] 解题思路: 先用map计数. 然后根据计数的值构造大根堆,也就是优先队列的大顶堆. 每一次都取最顶上的元素,然后出列.循环K次即可 代码: class Solution {

公仔面 314

spark 适配达梦数据库

spark 适配达梦数据库 版本 spark3.0.0 scala2.12.10 DM Database Server 64 V8 步骤一: 引驱动包: SBT方式: "com.dameng" % "Dm8JdbcDriver18" % "8.1.0.157", maven方式: <dependency> <groupId>com.dameng</groupId> <artifactId>Dm8JdbcDriver18</artifac

_@Eva@_的博客 2092

LeetCode 347.前 K 个高频元素

给你一个整数数组nums和一个整数k,请你返回其中出现频率前k高的元素。你可以按返回答案。k你所设计算法的时间复杂度优于O(n log n),其中n是数组大小。

weixin_50878507的博客 1140

不用变压器也能联网?手把手教你PHY芯片直连的3种实用方案

本文详细介绍了PHY芯片直连的3种实用方案,帮助开发者在物联网设备中实现更经济、更精简的网络连接设计。通过分析电压驱动型和电流驱动型PHY的核心原理,提供具体的电路配置和优化建议,确保信号质量的同时节省成本和空间。

smartcontract5的博客 334

【Clickhouse】Clickhouse写入报错keeper server rejected the connection during the handshake

我的clickhouse集群时不时的报这个错误All connection tries failed while connecting to ZooKeeper. nodes: xxx 到时写入数据失败 用的ck自带的keeper。你需要仔细检查ZooKeeper集群的配置和状态,确保所有节点都正常运行,并且能够正确地选举领导者。检查ZooKeeper的ACL以及ClickHouse连接所使用的凭据,确保它们被正确配置和授权。版本不兼容:有时,不同版本的软件之间可能存在不兼容性,导致连接问题。

九师兄 373

【LeetCode】347. 前 K 个高频元素(中等)——代码随想录算法训练营Day13

【LeetCode】347. 前 K 个高频元素

晴雪月乔的博客 605

uni-app - 文本展开 / 收起折叠功能,支持自定义样式(当文本内容超出规定行数后,展开收起折叠的功能)兼容 H5 / App / 小程序且易用更容易修改的插件组件源码,超详细的示例代码及注释

uniapp实现文本的展开与收起功能,uniapp展开全部和收起,uniapp里文本的展开与收起,uniapp中文本内容超出规定行数后展开收起的处理,UNIAPP兼容h5、微信小程序多行文本展开或收起,uni-app中,文字超出隐藏并显示省略号(实现展开、收起全文),uni-app中文本过长-实现折叠与展开效果,中文本内容超出规定行数(字数)后展开收起的处理,超出部分...显示,uniapp适用于uniapp多行文本溢出显示...,多行文本展开或收起,uni-app-文本展开/收起折叠功能,支

🏆 前端领域优质创作者 5644

每日一题:Leetcode-347 前K个高频元素

力扣题目解题思路java代码。

LIUCHANGSHUO的博客 1144

visio安装包

Microsoft Office Visio 是一款专业的制图软件。利用经过更新的形状、协作工具和数据链接图表,创建专业级图表以简化复杂的信息。

精雕软件(JDpaint) 5.5 绿色版

精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版精雕软件(JDpaint) 5.5 绿色版

Leetcode刷题(第347题)——前K个高频元素

一、题目 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你 可以按 任意顺序 返回答案。 二、示例 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 输入: nums = [1], k = 1 输出: [1] 三、思路 本题采用的算法思路是最小堆。 四、代码展示 /** * @param {number[]} nums * @param {number} k * @return {number[]} */ class Mi

weixin_47450807的博客 1284

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

LeetCode:347. 前 K 个高频元素

347. 前 K 个高频元素 给定一个非空的整数数组,返回其中出现频率前k高的元素。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] 提示: 你可以假设给定的k总是合理的,且 1 ≤ k ≤ 数组中不相同的元素的个数。 你的算法的时间复杂度必须优于 O(n log n) ,n是数组的大小。 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是...

梦~' 1080

ET2012新版免狗免安装绿色软件

ET2012新版免狗免安祖昂绿色软件。,新界面,新视觉,

Leetcode:347. 前 K 个高频元素(C++)

给你一个整数数组nums和一个整数k,请你返回其中出现频率前k高的元素。你可以按任意顺序返回答案。

Cosmoshhhyyy的博客 737

leetcode-347:前 K 个高频元素

leetcode-347:前 K 个高频元素题目解答 题目 题目链接 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] 解答 主要就分为以下几个步骤 要统计元素出现频率 对频率排序 找出前K个高频元素 class Solution: def topKFrequ

菊头蝙蝠的博客 842

一个算法题带你搞懂<堆结构>:347、给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

定义:堆(Heap)是计算机科学中一类特殊的数据结构的统称。堆通常是一个可以被看做一棵完全二叉树的数组对象。故通常我们用完全二叉树来维护一个一维数组。性质1)堆中某个节点的值总是不大于或不小于其父节点的值。2)堆总是一棵完全二叉树。完全二叉树:满足下面两点:1)如果将二叉树的深度设置为h,则除h层之外的所有层(1~h-1)中的节点数达到最大值(满二叉树)2)并且h层中的所有节点都连续地集中在最左侧就是一个完全的二叉树。

weixin_53028400的博客 962

【LeetCode】前 K 个高频元素(堆)

创建一个哈希表,用其存放数组中出现的元素以及每个元素出现的次数,先创建一个类numOfTimes , 其中有两个属性,一个key值,一个k值出现的次数,写一个类numsSortWayOfTimes继承Comparator方法接口,重写compare方法(对numOfTimes对象进行排序比较的方式---key值出现的次数times的大小),建立一个优先级队列大小为k,存储(元素与出现次数的)numOfTimes的对象 遍历队列后就会将出现次数最多的元素对象留在了堆中

m0_57248981的博客 874

LeetCode hot 100—前 K 个高频元素

给你一个整数数组nums和一个整数k,请你返回其中出现频率前k高的元素。你可以按返回答案。

rigidwill的博客 1107

力扣刷题:前 K 个高频元素(java实现)

题目:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] 提示: 1 <= nums.length <= 105 k 的取值范围是 [1, 数组中不相同的元素的个数] 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的 进阶:你所设计算法的

谦谦均的博客 1145

​LeetCode刷题实战347:前 K 个高频元素

算法的重要性,我就不多说了吧,想去大厂,就必须要经过基础知识和业务逻辑面试+算法面试。所以,为了提高大家的算法能力,这个公众号后续每天带大家做一道算法题,题目就从LeetCode上面选 !...

程序IT圈 265

347. 前 K 个高频元素

题目 给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。 示例 1: 输入: nums = [1,1,1,2,2,3], k = 2 输出: [1,2] 示例 2: 输入: nums = [1], k = 1 输出: [1] 提示: 1 <= nums.length <= 105 k 的取值范围是 [1, 数组中不相同的元素的个数] 题目数据保证答案唯一,换句话说,数组中前 k 个高频元素的集合是唯一的 进..

qq_43808588的博客 258

【Leetcode】347. 前 K 个高频元素

【Leetcode】347. 前 K 个高频元素

这是简介 534

2022-10-15:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。 你可以按 任意顺序 返回答案。 要求时间复杂度O(N)。 输入: nums = [1,1,1

力扣上测试了主流语言的运行速度和内存占用。运行速度上,rust最快,go最慢,但跟java差不多。内存占用上,rust最少,go比rust稍微多一点,java最多。2022-10-15:给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。输入: nums = [1,1,1,2,2,3], k = 2。词频统计,bfprt算法。你可以按 任意顺序 返回答案。代码用rust编写。要求时间复杂度O(N)。输出: [1,2]。

福大大架构师每日一题 2万+
上一篇: 数据结构与算法之堆: LeetCode 215. 数组中的第K个最大元素 (Ts, Py, Go版)
下一篇: 数据结构与算法之堆: LeetCode 23. 合并K个升序链表 (Ts, Py, Go版)
Wang's Blog
博客等级 码龄12年 7438粉丝 2421原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

Wang's Blog

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值