[docs update]经典LeetCode题目推荐+红黑树内容完善
@ -239,6 +239,8 @@ export default sidebar({
|
||||
icon: "suanfaku",
|
||||
collapsible: true,
|
||||
children: [
|
||||
"classical-algorithm-problems-recommendations",
|
||||
"common-data-structures-leetcode-recommendations",
|
||||
"string-algorithm-problems",
|
||||
"linkedlist-algorithm-problems",
|
||||
"the-sword-refers-to-offer",
|
||||
|
@ -1,4 +1,9 @@
|
||||
# 经典算法思想介绍
|
||||
---
|
||||
title: 经典算法思想总结(含LeetCode题目推荐)
|
||||
category: 计算机基础
|
||||
tag:
|
||||
- 算法
|
||||
---
|
||||
|
||||
## 贪心算法
|
||||
|
@ -1,4 +1,11 @@
|
||||
# 数组
|
||||
---
|
||||
title: 常见数据结构经典LeetCode题目推荐
|
||||
category: 计算机基础
|
||||
tag:
|
||||
- 算法
|
||||
---
|
||||
|
||||
## 数组
|
||||
|
||||
704.二分查找:https://leetcode.cn/problems/binary-search/
|
||||
|
||||
@ -6,7 +13,7 @@
|
||||
|
||||
977.有序数组的平方:https://leetcode.cn/problems/squares-of-a-sorted-array/
|
||||
|
||||
# 链表
|
||||
## 链表
|
||||
|
||||
707.设计链表:https://leetcode.cn/problems/design-linked-list/
|
||||
|
||||
@ -16,7 +23,7 @@
|
||||
|
||||
61.旋转链表:https://leetcode.cn/problems/rotate-list/
|
||||
|
||||
# 栈与队列
|
||||
## 栈与队列
|
||||
|
||||
232.用栈实现队列:https://leetcode.cn/problems/implement-queue-using-stacks/
|
||||
|
||||
@ -26,7 +33,7 @@
|
||||
|
||||
239.滑动窗口最大值:https://leetcode.cn/problems/sliding-window-maximum/
|
||||
|
||||
# 二叉树
|
||||
## 二叉树
|
||||
|
||||
105.从前序与中序遍历构造二叉树:https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
|
||||
|
||||
@ -40,10 +47,21 @@
|
||||
|
||||
530.二叉搜索树的最小绝对差:https://leetcode.cn/problems/minimum-absolute-difference-in-bst/
|
||||
|
||||
# 图
|
||||
## 图
|
||||
|
||||
200.岛屿数量:https://leetcode.cn/problems/number-of-islands/
|
||||
|
||||
207.课程表:https://leetcode.cn/problems/course-schedule/
|
||||
|
||||
210.课程表 II:https://leetcode.cn/problems/course-schedule-ii/
|
||||
|
||||
## 堆
|
||||
|
||||
215. 数组中的第 K 个最大元素:https://leetcode.cn/problems/kth-largest-element-in-an-array/
|
||||
|
||||
215. 数据流的中位数:https://leetcode.cn/problems/find-median-from-data-stream/
|
||||
|
||||
215. 前 K 个高频元素:https://leetcode.cn/problems/top-k-frequent-elements/
|
||||
|
||||
|
||||
|
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 26 KiB After Width: | Height: | Size: 12 KiB |
Before Width: | Height: | Size: 22 KiB After Width: | Height: | Size: 11 KiB |
Before Width: | Height: | Size: 30 KiB After Width: | Height: | Size: 13 KiB |
Before Width: | Height: | Size: 25 KiB After Width: | Height: | Size: 11 KiB |
@ -1,35 +1,41 @@
|
||||
---
|
||||
title: 红黑树
|
||||
category: 计算机基础
|
||||
tag:
|
||||
- 数据结构
|
||||
---
|
||||
|
||||
# 红黑树
|
||||
## 红黑树介绍
|
||||
|
||||
红黑树(Red Black Tree)是一种自平衡二叉查找树。它是在 1972 年由 Rudolf Bayer 发明的,当时被称为平衡二叉 B 树(symmetric binary B-trees)。后来,在 1978 年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。
|
||||
|
||||
由于其自平衡的特性,保证了最坏情形下在 O(logn) 时间复杂度内完成查找、增加、删除等操作,性能表现稳定。
|
||||
|
||||
在 JDK 中,`TreeMap`、`TreeSet` 以及 JDK1.8 的 `HashMap` 底层都用到了红黑树。
|
||||
|
||||
## 为什么需要红黑树?
|
||||
|
||||
红黑树的诞生就是为了解决二叉查找树的缺陷。
|
||||
|
||||
二叉查找树是一种基于比较的数据结构,它的每个节点都有一个键值,而且左子节点的键值小于父节点的键值,右子节点的键值大于父节点的键值。这样的结构可以方便地进行查找、插入和删除操作,因为只需要比较节点的键值就可以确定目标节点的位置。但是,二叉查找树有一个很大的问题,就是它的形状取决于节点插入的顺序。如果节点是按照升序或降序的方式插入的,那么二叉查找树就会退化成一个线性结构,也就是一个链表。这样的情况下,二叉查找树的性能就会大大降低,时间复杂度就会从 O(logn) 变为 O(n)。
|
||||
|
||||
红黑树的诞生就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。
|
||||
|
||||
## **红黑树特点**
|
||||
|
||||
1. 每个节点非红即黑。黑色决定平衡,红色不决定平衡。这对应了 2-3 树中一个节点内可以存放 1~2 个节点。
|
||||
2. 根节点总是黑色的。
|
||||
3. 每个叶子节点都是黑色的空节点(NIL 节点)。这里指的是红黑树都会有一个空的叶子节点,是红黑树自己的规则。
|
||||
4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定)。通常这条规则也叫不会有连续的红色节点。一个节点最多临时会有 3 个节点,中间是黑色节点,左右是红色节点。
|
||||
5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。每一层都只是有一个节点贡献了树高决定平衡性,也就是对应红黑树中的黑色节点。
|
||||
|
||||
正是这些特点才保证了红黑树的平衡,让红黑树的高度不会超过 2log(n+1)。
|
||||
|
||||
|
||||
## 红黑树数据结构
|
||||
|
||||
建立在 BST 二叉搜索树的基础上,AVL、2-3 树、红黑树都是自平衡二叉树(统称 B-树)。但相比于 AVL 树,高度平衡所带来的时间复杂度,红黑树对平衡的控制要宽松一些,红黑树只需要保证黑色节点平衡即可。
|
||||
|
||||
## **红黑树特点**
|
||||
|
||||
1. 每个节点非红即黑;
|
||||
|
||||
黑色决定平衡,红色不决定平衡。这对应了2-3树中一个节点内可以存放1~2个节点。
|
||||
|
||||
2. 根节点总是黑色的;
|
||||
|
||||
3. 每个叶子节点都是黑色的空节点(NIL 节点);
|
||||
|
||||
这里指的是红黑树都会有一个空的叶子节点,是红黑树自己的规则。
|
||||
|
||||
4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定);
|
||||
|
||||
通常这条规则也叫不会有连续的红色节点。一个节点最多临时会有3个节点,中间是黑色节点,左右是红色节点。
|
||||
|
||||
5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。
|
||||
|
||||
每一层都只是有一个节点贡献了树高决定平衡性,也就是对应红黑树中的黑色节点。
|
||||
|
||||
## 红黑树结构实现
|
||||
|
||||
```java
|
||||
@ -80,10 +86,9 @@ public class Node {
|
||||
|
||||

|
||||
|
||||
**红黑树的应用**:TreeMap、TreeSet 以及 JDK1.8 的 HashMap 底层都用到了红黑树。
|
||||
## 文章推荐
|
||||
|
||||
**为什么要用红黑树?** 简单来说红黑树就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。详细了解可以查看 [漫画:什么是红黑树?](https://juejin.im/post/5a27c6946fb9a04509096248#comment)(也介绍到了二叉查找树,非常推荐)
|
||||
|
||||
**相关阅读**:[《红黑树深入剖析及 Java 实现》](https://zhuanlan.zhihu.com/p/24367771)(美团点评技术团队)
|
||||
- [《红黑树深入剖析及 Java 实现》 - 美团点评技术团队](https://zhuanlan.zhihu.com/p/24367771)
|
||||
- [漫画:什么是红黑树? - 程序员小灰](https://juejin.im/post/5a27c6946fb9a04509096248#comment)(也介绍到了二叉查找树,非常推荐)
|
||||
|
||||
<!-- @include: @article-footer.snippet.md -->
|
||||
|
@ -647,7 +647,7 @@ System.out.println(aa==bb);// true
|
||||
|
||||
会创建 1 或 2 个字符串对象。
|
||||
|
||||
1、如果字符串常量池中不存在字符串对象“abc”的引用,那么它将首先在字符串常量池中创建,然后在堆空间中创建,因此将创建总共 2 个字符串对象。
|
||||
1、如果字符串常量池中不存在字符串对象“abc”的引用,那么它会在堆上创建两个字符串对象,其中一个字符串对象的引用会被保存在字符串常量池中。
|
||||
|
||||
示例代码(JDK 1.8):
|
||||
|
||||
|
@ -24,6 +24,10 @@ icon: codelibrary-fill
|
||||
- [excel-streaming-reader](https://github.com/monitorjbl/excel-streaming-reader):Excel 流式代码风格读取工具(只支持读取 XLSX 文件),基于 Apache POI 封装,同时保留标准 POI API 的语法。
|
||||
- [myexcel](https://github.com/liaochong/myexcel):一个集导入、导出、加密 Excel 等多项功能的工具包。
|
||||
|
||||
### Word
|
||||
|
||||
- [poi-tl](https://github.com/Sayi/poi-tl):基于 Apache POI 的 Word 模板引擎,可以根据 Word 模板和数据生成 Word 文档,所见即所得!
|
||||
|
||||
### JSON
|
||||
|
||||
- [JsonPath](https://github.com/json-path/JsonPath):处理 JSON 数据的工具库。
|
||||
|
@ -176,7 +176,7 @@ Kafka、Dubbo、ZooKeeper、Netty、Caffeine、Akka 中都有对时间轮的实
|
||||
|
||||

|
||||
|
||||
上图的时间轮,第 1 层的时间精度为 1 ,第 2 层的时间精度为 20 ,第 3 层的时间精度为 400。假如我们需要添加一个 350s 后执行的任务 A 的话(当前时间是 0s),这个任务会被放在第 2 层(因为第二层的时间跨度为 20\*20=400>350)的第 350/20=17 个时间格子。
|
||||
上图的时间轮(ms -> s),第 1 层的时间精度为 1 ,第 2 层的时间精度为 20 ,第 3 层的时间精度为 400。假如我们需要添加一个 350s 后执行的任务 A 的话(当前时间是 0s),这个任务会被放在第 2 层(因为第二层的时间跨度为 20\*20=400>350)的第 350/20=17 个时间格子。
|
||||
|
||||
当第一层转了 17 圈之后,时间过去了 340s ,第 2 层的指针此时来到第 17 个时间格子。此时,第 2 层第 17 个格子的任务会被移动到第 1 层。
|
||||
|
||||
|