20个经典数据结构与算法,300幅算法手绘图解,带你领略算法之美

  一些经典的数据结构和算法图书,偏重理论,读者学起来可能感觉比较枯燥。一些趣谈类的数据结构和算法图书,虽然容易读懂,但往往内容不够全面。另外,很多数据结构和算法图书缺少真实的开发场景,读者很难将理论和实践相结合。

  刚好有这样一本书刚刚出版,解决了上述问题。

  

  数据结构与算法之美(全彩印刷)

  本书全面、系统地讲解了常用、常考的数据结构和算法,并结合 300多幅图和上百段代码,让内容变得更加通俗易懂。同时,对于每个知识点,本书结合真实的应用场景进行讲解,采用一问一答的讲解模式,让读者不仅可以掌握理论知识,还可以掌握如何将数据结构和算法应用到实际的开发工作中。

  前Google工程师算法面试和实战经验总结

  

  算法学习、刷题、面试一站式服务,十万+读者验证过的、为求职面试者、工程师量身打造。

  

  本书分为 11 章。第 1 章介绍复杂度分析方法。

  第 2 章介绍数组、链表、栈、队列这些基础的线性表数据结构。

  第 3 章介绍递归编程技巧、8 种经典排序、二分查找及二分查找的变体问题。

  第 4 章介绍哈希表、位图、哈希算法和布隆过滤器。

  第 5 章介绍树相关的各种数据结构,包括二叉树、二叉查找树、平衡二叉查找树、递归树和 B+树。

  第 6 章介绍堆,以及堆的各种应用,包括堆排序、优先级队列、求 Top K、求中位数和求百分位数。

  第 7 章介绍跳表、并查集、线段树、树状数组这些比较高级的数据结构。

  第 8 章介绍字符串匹配算法,包括 BF 算法、RK 算法、BM 算法、KMP 算法、Trie 树和 AC 自动机。

  第 9 章介绍图及相关算法,包括深度优先搜索、广度优先搜索、拓扑排序、Dijkstra 算法、Floyd 算法、A*算法、最小生成树算法、最大流算法和最大二分匹配等。

  第 10 章介绍 4 种算法思想,包括贪心、分治、回溯和动态规划。

  第 11 章介绍 4 个经典项目中的数据结构和算法的应用,包括 Redis、搜索引擎、鉴权限流和短网址服务。另外,附录 A 为每一章节的思考题的解答

  对算法和数据结构的学习,是读者对逻辑思维能力的锻炼。对于程序员,最为重要的能力是解决问题的能力。学习算法、掌握数据结构的应用,可以让读者具备科学的思维方式。通过对算法和数据结构的学习,读者不但可以提升自己在面试中的竞争力,而且在工作中应对边缘、性能问题时会更加从容和自信。本书从常用的数据结构与算法入手,采用和实际工程问题结合的讲解形式,可以带领读者系统化地学习、解读这些经典的计算机科学知识。

  ——张云浩(Hercy) 力扣(LeetCode)CEO

  算法之难,在于将精巧的逻辑,通过合适的数据结构,用编程语言展开。在某种程度上,数据结构和算法可以说是计算机应用领域的底层逻辑,而本书正是我们学习这一底层逻辑的必读图书。让我们通过本书的学习一起感受算法和数据结构之美。

  ——茹炳晟 腾讯T4级专家

  我是本书作者的专栏的订阅者。本书的特点是对算法的多层次讲解,从算法基础知识的讲解到落地实践。如果你是算法知识的初学者,那么可以用它来入门;如果你是一个求职者,那么可以用它来准备面试。

  ——刘超 《趣谈网络协议》《趣谈Linux操作系统》作者

  目录

  第1章?复杂度分析 1

  1.1?复杂度分析(上):如何分析代码的执行效率和资源消耗 2

  1.1.1?复杂度分析的意义 2

  1.1.2?大O复杂度表示法 2

  1.1.3?时间复杂度分析方法 4

  1.1.4?几种常见的时间复杂度量级 5

  1.1.5?空间复杂度分析方法 7

  1.1.6?内容小结 7

  1.1.7?思考题 8

  1.2?复杂度分析(下):详解最好、最坏、平均、均摊这4种时间复杂度 8

  1.2.1?最好时间复杂度和最坏时间复杂度 8

  1.2.2?平均时间复杂度 9

  1.2.3?均摊时间复杂度 10

  1.2.4?内容小结 11

  1.2.5?思考题 12

  第2章?数组、链表、栈和队列 13

  2.1?数组(上):为什么数组的下标一般从0开始编号 14

  2.1.1?数组的定义 14

  2.1.2?寻址公式和随机访问特性 15

  2.1.3?低效的插入和删除操作 15

  2.1.4?警惕数组访问越界问题 16

  2.1.5?容器能否完全替代数组 17

  2.1.6?解答本节开篇问题 18

  2.1.7?内容小结 18

  2.1.8?思考题 18

  2.2?数组(下):数据结构中的数组和编程语言中的数组的区别 19

  2.2.1?C/C++中数组的实现方式 19

  2.2.2?Java中数组的实现方式 20

  2.2.3?JavaScript中数组的实现方式 22

  2.2.4?内容小结 23

  2.2.5?思考题 23

  2.3?链表(上):如何基于链表实现LRU缓存淘汰算法 23

  2.3.1?链表的底层存储结构 24

  2.3.2?链表的定义和操作 24

  2.3.3?链表的变形结构 26

  2.3.4?链表与数组的性能对比 28

  2.3.5?解答本节开篇问题 29

  2.3.6?内容小结 29

  2.3.7?思考题 30

  2.4?链表(下):借助哪些技巧可以轻松地编写链表相关的复杂代码 30

  2.4.1?技巧1:理解指针或引用的含义 30

  2.4.2?技巧2:警惕指针丢失和内存泄露 30

  2.4.3?技巧3:利用“哨兵”简化代码 31

  2.4.4?技巧4:留意边界条件和特殊情况 33

  2.4.5?技巧5:举例画图,辅助思考 34

  2.4.6?技巧6:多写多练,没有捷径 34

  2.4.7?内容小结 34

  2.4.8?思考题 35

  2.5?栈:如何实现浏览器的前进和后退功能 35

  2.5.1?栈的定义 35

  2.5.2?顺序栈和链式栈 35

  2.5.3?支持动态扩容的顺序栈 36

  2.5.4?栈在函数调用中的应用 37

  2.5.5?栈在表达式求值中的应用 38

  2.5.6?栈在括号匹配中的应用 38

  2.5.7?解答本节开篇问题 39

  2.5.8?内容小结 40

  2.5.9?思考题 40

  2.6?队列:如何实现线程池等有限资源池的请求排队功能 40

  2.6.1?队列的定义 40

  2.6.2?顺序队列和链式队列 41

  2.6.3?循环队列 42

  2.6.4?阻塞队列和并发队列 44

  2.6.5?解答本节开篇问题 44

  2.6.6?内容小结 45

  2.6.7?思考题 45

  第3章?递归、排序、二分查找 46

  3.1?递归:如何用3行代码找到“最终推荐人” 47

  3.1.1?什么是递归 47

  3.1.2?递归需要满足的3个条件 48

  3.1.3?如何编写递归代码 48

  3.1.4?编写递归代码的难点 49

  3.1.5?警惕递归代码出现堆栈溢出 49

  3.1.6?警惕递归代码的重复计算问题 50

  3.1.7?将递归代码改写为非递归代码 51

  3.1.8?解答本节开篇问题 52

  3.1.9?内容小结 52

  3.1.10?思考题 52

  3.2?尾递归:如何借助尾递归避免递归过深导致的堆栈溢出 53

  3.2.1?递归产生堆栈溢出的原因 53

  3.2.2?什么样的递归代码可以改写为尾递归 54

  3.2.3?尾递归真的可以避免堆栈溢出吗 54

  3.2.4?思考题 55

  3.3?排序算法基础:从哪几个方面分析排序算法 55

  3.3.1?排序算法的执行效率 55

  3.3.2?排序算法的内存消耗 56

  3.3.3?排序算法的稳定性 56

  3.3.4?内容小结 57

  3.3.5?思考题 57

  3.4?O(n2)排序:为什么插入排序比冒泡排序更受欢迎 58

  3.4.1?冒泡排序 58

  3.4.2?插入排序 60

  3.4.3?选择排序 62

  3.4.4?解答本节开篇问题 63

  3.4.5?内容小结 64

  3.4.6?思考题 64

  3.5?O(nlogn)排序:如何借助快速排序思想快速查找第K大元素 64

  3.5.1?归并排序的原理和实现 64

  3.5.2?归并排序的性能分析 66

  3.5.3?快速排序的原理和实现 68

  3.5.4?快速排序的性能分析 70

  3.5.5?解答本节开篇问题 71

  3.5.6?内容小结 72

  3.5.7?思考题 72

  3.6?线性排序:如何根据年龄给100万个用户排序 72

  3.6.1?桶排序 73

  3.6.2?计数排序 74

  3.6.3?基数排序 76

  3.6.4?解答本节开篇问题 77

  3.6.5?内容小结 77

  3.6.6?思考题 77

  3.7?排序优化:如何实现一个高性能的通用的排序函数 78

  3.7.1?如何选择合适的排序算法 78

  3.7.2?如何优化快速排序 79

  3.7.3?排序函数举例分析 79

  3.7.4?内容小结 80

  3.7.5?思考题 80

  3.8?二分查找:如何用最省内存的方式实现快速查找功能 80

  3.8.1?无处不在的二分思想 81

  3.8.2?O(logn)惊人的查找速度 82

  3.8.3?二分查找的递归与非递归实现 82

  3.8.4?二分查找应用场景的局限性 83

  3.8.5?解答本节开篇问题 84

  3.8.6?内容小结 85

  3.8.7?思考题 85

  3.9?二分查找的变体:如何快速定位IP地址对应的归属地 85

  3.9.1?什么是二分查找变体问题 86

  3.9.2?变体问题1:查找第一个值等于给定值的元素 86

  3.9.3?变体问题2:查找最后一个值等于给定值的元素 88

  3.9.4?变体问题3:查找第一个值大于或等于给定值的元素 88

  3.9.5?变体问题4:查找最后一个值小于或等于给定值的元素 89

  3.9.6?解答本节开篇问题 89

  3.9.7?内容小结 90

  3.9.8?思考题 90

  第4章?哈希表、位图和哈希算法 91

  4.1?哈希表(上):Word软件的单词拼写检查功能是如何实现的 92

  4.1.1?哈希思想 92

  4.1.2?哈希函数 93

  4.1.3?哈希冲突 93

  4.1.4?解答本节开篇问题 95

  4.1.5?内容小结 95

  4.1.6?思考题 96

  4.2?哈希表(中):如何打造一个工业级的哈希表 96

  4.2.1?设计哈希函数 96

  4.2.2?解决装载因子过大的问题 97

  4.2.3?避免低效的扩容 98

  4.2.4?选择合适的冲突解决方法 99

  4.2.5?工业级的哈希表举例分析 100

  4.2.6?解答本节开篇问题 100

  4.2.7?内容小结 101

  4.2.8?思考题 101

  4.3?哈希表(下):如何利用哈希表优化LRU缓存淘汰算法 101

  4.3.1?LRU缓存淘汰算法 102

  4.3.2?Java LinkedHashMap 104

  4.3.3?内容小结 105

  4.3.4?思考题 105

  4.4?位图:如何实现网页“爬虫”中的网址链接去重功能 106

  4.4.1?基于哈希表的解决方案 106

  4.4.2?基于位图的解决方案 106

  4.4.3?基于布隆过滤器的解决方案 108

  4.4.4?回答本节开篇问题 110

  4.4.5?内容小结 110

  4.4.6?思考题 111

  4.5?哈希算法:如何防止数据库脱库后用户信息泄露 111

  4.5.1?哈希算法介绍 111

  4.5.2?应用1:安全加密 112

  4.5.3?应用2:唯一标识 113

  4.5.4?应用3:数据校验 113

  4.5.5?应用4:哈希函数 113

  4.5.6?应用5:负载均衡 114

  4.5.7?应用6:数据分片 114

  4.5.8?应用7:分布式存储 115

  4.5.9?解答本节开篇问题 116

  4.5.10?内容小结 116

  4.5.11?思考题 116

  第5章?树 117

  5.1?树和二叉树:什么样的二叉树适合用数组存储 118

  5.1.1?树的定义 118

  5.1.2?二叉树的定义 118

  5.1.3?二叉树的存储 119

  5.1.4?二叉树的遍历 120

  5.1.5?解答本节开篇问题 122

  5.1.6?内容小结 122

  5.1.7?思考题 122

  5.2?二叉查找树:相比哈希表,二叉查找树有何优势 122

  5.2.1?二叉查找树的定义和操作 123

  5.2.2?支持重复数据的二叉查找树 126

  5.2.3?二叉查找树的性能分析 126

  5.2.4?解答本节开篇问题 127

  5.2.5?内容小结 128

  5.2.6?思考题 128

  5.3?平衡二叉查找树:为什么红黑树如此受欢迎 128

  5.3.1?平衡二叉查找树的定义 128

  5.3.2?红黑树的定义 129

  5.3.3?红黑树的性能分析 129

  5.3.4?解答本节开篇问题 130

  5.3.5?内容小结 130

  5.3.6?思考题 131

  5.4?递归树:如何借助树求递归算法的时间复杂度 131

  5.4.1?递归树时间复杂度分析法 131

  5.4.2?实战1:快速排序的时间复杂度分析 132

  5.4.3?实战2:斐波那契数列的时间复杂度分析 133

  5.4.4?实战3:全排列的时间复杂度分析 133

  5.4.5?内容小结 135

  5.4.6?思考题 135

  5.5?B+树:MySQL数据库索引是如何实现的 135

  5.5.1?典型需求:按值查询和按区间查询 135

  5.5.2?基于哈希表和二叉查找树的解决方案 136

  5.5.3?基于B+树的解决方案 136

  5.5.4?内容小结 139

  5.5.5?思考题 140

  第6章?堆 141

  6.1?堆:如何维护动态集合的最值 142

  6.1.1?堆的定义 142

  6.1.2?堆的存储 142

  6.1.3?往堆中插入元素 143

  6.1.4?删除堆顶元素 144

  6.1.5?删除任意元素 145

  6.1.6?堆的性能分析 145

  6.1.7?解答本节开篇问题 145

  6.1.8?内容小结 146

  6.1.9?思考题 146

  6.2?堆排序:为什么说堆排序没有快速排序快 147

  6.2.1?堆排序之建堆 147

  6.2.2?堆排序之排序 149

  6.2.3?堆排序的性能分析 149

  6.2.4?解答本节开篇问题 150

  6.2.5?内容小结 150

  6.2.6?思考题 151

  6.3?堆的应用:如何快速获取Top 10热门搜索关键词 151

  6.3.1?堆的应用1:优先级队列 151

  6.3.2?堆的应用2:求Top K 152

  6.3.3?堆的应用3:求中位数和百分位数 153

  6.3.4?解答本节开篇问题 155

  6.3.5?内容小结 155

  6.3.6?思考题 156

  第7章?跳表、并查集、线段树和树状数组 157

  7.1?跳表:Redis中的有序集合类型是如何实现的 158

  7.1.1 跳表的由来 158

  7.1.2 用跳表查询到底有多快 159

  7.1.3 跳表是不是很浪费内存 160

  7.1.4 高效插入和删除 161

  7.1.5 跳表索引动态更新 162

  7.1.6 解答本节开篇问题 162

  7.1.7 内容小结 163

  7.1.8 思考题 163

  7.2?并查集:路径压缩和按秩合并这两个优化是否冲突 163

  7.2.1 并查集的由来 163

  7.2.2 基于链表的实现思路 164

  7.2.3 基于树的实现思路 166

  7.2.4 内容小结 168

  7.2.5 思考题 168

  7.3?线段树:如何查找猎聘网中积分排在第K位的猎头 168

  7.3.1 区间统计问题 169

  7.3.2 线段树的其他应用 172

  7.3.3 解答本节开篇问题 174

  7.3.4 内容小结 174

  7.3.5 思考题 174

  7.4?树状数组:如何实现一个高性能、低延迟的实时排行榜 174

  7.4.1 “前缀和”问题 175

  7.4.2 树状数组与线段树的对比 177

  7.4.3 解答本节开篇问题 177

  7.4.4 内容小结 178

  7.4.5 思考题 178

  第8章?字符串匹配算法 179

  8.1?BF算法:编程语言中的查找、替换函数是怎样实现的 180

  8.1.1 BF算法的原理与实现 180

  8.1.2 BF算法的性能分析 181

  8.1.3 解答本节开篇问题 181

  8.1.4 内容小结 182

  8.1.5 思考题 182

  8.2?RK算法:如何借助哈希算法实现高效的字符串匹配 182

  8.2.1 RK算法的原理与实现 182

  8.2.2 RK算法的性能分析 183

  8.2.3 内容小结 184

  8.2.4 思考题 184

  8.3?BM算法:如何实现文本编辑器中的查找和替换功能 185

  8.3.1 BM算法的核心思想 185

  8.3.2 BM算法的原理分析 186

  8.3.3 BM算法的代码实现 188

  8.3.4 BM算法的性能分析 192

  8.3.5 解答本节开篇问题 193

  8.3.6 内容小结 193

  8.3.7 思考题 193

  8.4?KMP算法:如何借助BM算法理解KMP算法 194

  8.4.1 KMP算法的基本原理 194

  8.4.2 失效函数的计算方法 196

  8.4.3 KMP算法的性能分析 197

  8.4.4 内容小结 198

  8.4.5 思考题 198

  8.5?Trie树:如何实现搜索引擎的搜索关键词提示功能 198

  8.5.1 Trie树的定义 199

  8.5.2 Trie树的代码实现 200

  8.5.3 Trie树的性能分析 201

  8.5.4 Trie树与哈希表、红黑树的比较 202

  8.5.5 解答本节开篇问题 202

  8.5.6 内容小结 203

  8.5.7 思考题 204

  8.6?AC自动机:如何用多模式串匹配实现敏感词过滤 204

  8.6.1 基于单模式串的敏感词过滤 204

  8.6.2 基于Trie树的敏感词过滤 205

  8.6.3 基于AC自动机的敏感词过滤 205

  8.6.4 AC自动机的性能分析 208

  8.6.5 内容小结 209

  8.6.6 思考题 209

  第9章?图 210

  9.1?图的表示:如何存储微博、微信等社交网络中的好友关系 211

  9.1.1 图的定义 211

  9.1.2 邻接矩阵的存储方法 212

  9.1.3 邻接表的存储方法 213

  9.1.4 解答本节开篇问题 214

  9.1.5 内容小结 215

  9.1.6 思考题 215

  9.2?深度优先搜索和广度优先搜索:如何找出社交网络中的三度好友关系 216

  9.2.1 什么是搜索算法 216

  9.2.2 广度优先搜索 217

  9.2.3 深度优先搜索 219

  9.2.4 解答本节开篇问题 220

  9.2.5 内容小结 220

  9.2.6 思考题 220

  9.3?拓扑排序:如何确定代码源文件的编译依赖关系 221

  9.3.1 什么是拓扑排序 221

  9.3.2 利用Kahn算法实现拓扑排序 222

  9.3.3 利用深度优先搜索实现拓扑排序 222

  9.3.4 利用拓扑排序检测环 223

  9.3.5 解答本节开篇问题 224

  9.3.6 内容小结 224

  9.3.7 思考题 224

  9.4?单源最短路径:地图软件如何“计算”最优出行路线 225

  9.4.1 最短路径算法介绍 225

  9.4.2 Dijkstra算法的原理与实现 225

  9.4.3 Dijkstra算法的性能分析 228

  9.4.4 Dijkstra算法思想的应用 228

  9.4.5 解答本节开篇问题 229

  9.4.6 内容小结 230

  9.4.7 思考题 230

  9.5?多源最短路径:如何利用Floyd算法解决传递闭包问题 231

  9.5.1 Floyd算法的原理与实现 231

  9.5.2 Floyd算法的性能分析 232

  9.5.3 利用Floyd算法求解传递闭包 232

  9.5.4 内容小结 233

  9.5.5 思考题 233

  9.6?启发式搜索:如何用A*算法实现游戏中的寻路功能 233

  9.6.1 什么是统招次优路线 234

  9.6.2 A*算法的原理与实现 234

  9.6.3 A*算法与Dijkstra算法的对比 236

  9.6.4 解答本节开篇问题 237

  9.6.5 内容小结 237

  9.6.6 思考题 238

  9.7?最小生成树:如何随机生成游戏中的迷宫地图 238

  9.7.1 什么是最小生成树 238

  9.7.2 Kruskal算法的原理与实现 239

  9.7.3 Prim算法的原理与实现 240

  9.7.4 解答本节开篇问题 242

  9.7.5 内容小结 244

  9.7.6 思考题 245

  9.8?最大流:如何解决单身交友联谊中的最多匹配问题 245

  9.8.1 什么是最大流 245

  9.8.2 Ford-Fulkerson方法 246

  9.8.3 Edmonds-Karp算法 247

  9.8.4 最大二分匹配 249

  9.8.5 解答本节开篇问题 249

  9.8.6 内容小结 249

  9.8.7 思考题 250

  第10章?贪心、分治、回溯和动态规划 251

  10.1?贪心算法:如何利用贪心算法实现霍夫曼编码 252

  10.1.1 如何理解贪心算法 252

  10.1.2 贪心算法的应用示例 253

  10.1.3 解答本节开篇问题 255

  10.1.4 内容小结 256

  10.1.5 思考题 256

  10.2?分治算法:谈一谈大规模计算框架MapReduce中的分治思想 256

  10.2.1 如何理解分治算法 257

  10.2.2 分治算法的应用示例 257

  10.2.3 分治算法在大数据处理中的应用 259

  10.2.4 解答本节开篇问题 259

  10.2.5 内容小结 260

  10.2.6 思考题 260

  10.3?回溯算法:从电影《蝴蝶效应》中学习回溯算法的核心思想 260

  10.3.1 如何理解回溯算法 261

  10.3.2 八皇后问题 261

  10.3.3 0-1背包问题 262

  10.3.4 正则表达式匹配问题 263

  10.3.5 内容小结 264

  10.3.6 思考题 264

  10.4?初识动态规划:如何巧妙解决“双11”购物时的凑单问题 264

  10.4.1 动态规划的学习路线 265

  10.4.2 利用动态规划解决0-1背包问题 265

  10.4.3 0-1背包问题的升级版 269

  10.4.4 解答本节开篇问题 270

  10.4.5 内容小结 271

  10.4.6 思考题 272

  10.5?动态规划理论:彻底理解最优子结构、无后效性和重复子问题 272

  10.5.1 “一个模型和三个特征”理论介绍 272

  10.5.2 “一个模型和三个特征”的应用示例 273

  10.5.3 动态规划的两种解题方法 274

  10.5.4 4种算法思想的比较分析 277

  10.5.5 内容小结 277

  10.5.6 思考题 278

  10.6?动态规划实战:如何实现搜索引擎中的拼写纠错功能 278

  10.6.1 如何量化两个字符串的相似度 278

  10.6.2 如何通过编程计算莱文斯坦距离 279

  10.6.3 如何通过编程计算最长公共子串长度 281

  10.6.4 解答本节开篇问题 282

  10.6.5 内容小结 283

  10.6.6 思考题 283

  第11章?数据结构和算法实战 284

  11.1?实战1:剖析Redis的常用数据类型对应的数据结构 285

  11.1.1 Redis数据库介绍 285

  11.1.2 列表(list) 285

  11.1.3 哈希(hash) 286

  11.1.4 集合(set) 286

  11.1.5 有序集合(sorted set) 287

  11.1.6 数据结构的持久化问题 287

  11.1.7 总结和引申 288

  11.1.8 思考题 288

  11.2?实战2:剖析搜索引擎背后的经典数据结构和算法 288

  11.2.1 搜索引擎系统的整体介绍 288

  11.2.2 搜集 289

  11.2.3 分析 290

  11.2.4 索引 292

  11.2.5 查询 292

  11.2.6 总结和引申 293

  11.2.7 思考题 293

  11.3?实战3:剖析微服务鉴权和限流背后的数据结构和算法 293

  11.3.1 鉴权背景介绍 294

  11.3.2 如何实现快速鉴权 294

  11.3.3 限流背景介绍 297

  11.3.4 如何实现精准限流 297

  11.3.5 总结和引申 298

  11.3.6 思考题 299

  11.4?实战4:用学过的数据结构和算法实现短网址服务 299

  11.4.1 短网址服务的整体介绍 299

  11.4.2 通过哈希算法生成短网址 299

  11.4.3 通过ID生成器生成短网址 302

  11.4.4 总结和引申 303

  11.4.5 思考题 303

  附录A?思考题答案 304

  

  

  

  

  

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值