[docs update]经典LeetCode题目推荐+红黑树内容完善
@ -239,6 +239,8 @@ export default sidebar({
|
|||||||
icon: "suanfaku",
|
icon: "suanfaku",
|
||||||
collapsible: true,
|
collapsible: true,
|
||||||
children: [
|
children: [
|
||||||
|
"classical-algorithm-problems-recommendations",
|
||||||
|
"common-data-structures-leetcode-recommendations",
|
||||||
"string-algorithm-problems",
|
"string-algorithm-problems",
|
||||||
"linkedlist-algorithm-problems",
|
"linkedlist-algorithm-problems",
|
||||||
"the-sword-refers-to-offer",
|
"the-sword-refers-to-offer",
|
||||||
|
@ -1,4 +1,9 @@
|
|||||||
# 经典算法思想介绍
|
---
|
||||||
|
title: 经典算法思想总结(含LeetCode题目推荐)
|
||||||
|
category: 计算机基础
|
||||||
|
tag:
|
||||||
|
- 算法
|
||||||
|
---
|
||||||
|
|
||||||
## 贪心算法
|
## 贪心算法
|
||||||
|
|
||||||
@ -19,11 +24,11 @@
|
|||||||
|
|
||||||
121.买卖股票的最佳时机:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
|
121.买卖股票的最佳时机:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
|
||||||
|
|
||||||
122.买卖股票的最佳时机II:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
|
122.买卖股票的最佳时机 II:https://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
|
||||||
|
|
||||||
55.跳跃游戏:https://leetcode.cn/problems/jump-game/
|
55.跳跃游戏:https://leetcode.cn/problems/jump-game/
|
||||||
|
|
||||||
45.跳跃游戏II:https://leetcode.cn/problems/jump-game-ii/
|
45.跳跃游戏 II:https://leetcode.cn/problems/jump-game-ii/
|
||||||
|
|
||||||
## 动态规划
|
## 动态规划
|
||||||
|
|
||||||
@ -31,15 +36,15 @@
|
|||||||
|
|
||||||
动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的。
|
动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的。
|
||||||
|
|
||||||
经典题目:01背包、完全背包
|
经典题目:01 背包、完全背包
|
||||||
|
|
||||||
### 一般解题步骤
|
### 一般解题步骤
|
||||||
|
|
||||||
- 确定dp数组(dp table)以及下标的含义
|
- 确定 dp 数组(dp table)以及下标的含义
|
||||||
- 确定递推公式
|
- 确定递推公式
|
||||||
- dp数组如何初始化
|
- dp 数组如何初始化
|
||||||
- 确定遍历顺序
|
- 确定遍历顺序
|
||||||
- 举例推导dp数组
|
- 举例推导 dp 数组
|
||||||
|
|
||||||
### LeetCode
|
### LeetCode
|
||||||
|
|
||||||
@ -63,7 +68,7 @@
|
|||||||
|
|
||||||
件时,就“回溯”返回,尝试别的路径。其本质就是穷举。
|
件时,就“回溯”返回,尝试别的路径。其本质就是穷举。
|
||||||
|
|
||||||
经典题目:8皇后
|
经典题目:8 皇后
|
||||||
|
|
||||||
### 一般解题步骤
|
### 一般解题步骤
|
||||||
|
|
||||||
@ -77,19 +82,19 @@
|
|||||||
|
|
||||||
39.组合总和:https://leetcode.cn/problems/combination-sum/
|
39.组合总和:https://leetcode.cn/problems/combination-sum/
|
||||||
|
|
||||||
40.组合总和II:https://leetcode.cn/problems/combination-sum-ii/
|
40.组合总和 II:https://leetcode.cn/problems/combination-sum-ii/
|
||||||
|
|
||||||
78.子集:https://leetcode.cn/problems/subsets/
|
78.子集:https://leetcode.cn/problems/subsets/
|
||||||
|
|
||||||
90.子集II:https://leetcode.cn/problems/subsets-ii/
|
90.子集 II:https://leetcode.cn/problems/subsets-ii/
|
||||||
|
|
||||||
51.N皇后:https://leetcode.cn/problems/n-queens/
|
51.N 皇后:https://leetcode.cn/problems/n-queens/
|
||||||
|
|
||||||
## 分治算法
|
## 分治算法
|
||||||
|
|
||||||
### 算法思想
|
### 算法思想
|
||||||
|
|
||||||
将一个规模为N的问题分解为K个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。
|
将一个规模为 N 的问题分解为 K 个规模较小的子问题,这些子问题相互独立且与原问题性质相同。求出子问题的解,就可得到原问题的解。
|
||||||
|
|
||||||
经典题目:二分查找、汉诺塔问题
|
经典题目:二分查找、汉诺塔问题
|
||||||
|
|
||||||
@ -105,5 +110,5 @@
|
|||||||
|
|
||||||
148.排序列表:https://leetcode.cn/problems/sort-list/
|
148.排序列表:https://leetcode.cn/problems/sort-list/
|
||||||
|
|
||||||
23.合并k个升序链表:https://leetcode.cn/problems/merge-k-sorted-lists/
|
23.合并 k 个升序链表:https://leetcode.cn/problems/merge-k-sorted-lists/
|
||||||
|
|
@ -1,36 +1,43 @@
|
|||||||
# 数组
|
---
|
||||||
|
title: 常见数据结构经典LeetCode题目推荐
|
||||||
|
category: 计算机基础
|
||||||
|
tag:
|
||||||
|
- 算法
|
||||||
|
---
|
||||||
|
|
||||||
|
## 数组
|
||||||
|
|
||||||
704.二分查找:https://leetcode.cn/problems/binary-search/
|
704.二分查找:https://leetcode.cn/problems/binary-search/
|
||||||
|
|
||||||
80.删除有序数组中的重复项II:https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii
|
80.删除有序数组中的重复项 II:https://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii
|
||||||
|
|
||||||
977.有序数组的平方:https://leetcode.cn/problems/squares-of-a-sorted-array/
|
977.有序数组的平方:https://leetcode.cn/problems/squares-of-a-sorted-array/
|
||||||
|
|
||||||
# 链表
|
## 链表
|
||||||
|
|
||||||
707.设计链表:https://leetcode.cn/problems/design-linked-list/
|
707.设计链表:https://leetcode.cn/problems/design-linked-list/
|
||||||
|
|
||||||
206.反转链表:https://leetcode.cn/problems/reverse-linked-list/
|
206.反转链表:https://leetcode.cn/problems/reverse-linked-list/
|
||||||
|
|
||||||
92.反转链表II:https://leetcode.cn/problems/reverse-linked-list-ii/
|
92.反转链表 II:https://leetcode.cn/problems/reverse-linked-list-ii/
|
||||||
|
|
||||||
61.旋转链表:https://leetcode.cn/problems/rotate-list/
|
61.旋转链表:https://leetcode.cn/problems/rotate-list/
|
||||||
|
|
||||||
# 栈与队列
|
## 栈与队列
|
||||||
|
|
||||||
232.用栈实现队列:https://leetcode.cn/problems/implement-queue-using-stacks/
|
232.用栈实现队列:https://leetcode.cn/problems/implement-queue-using-stacks/
|
||||||
|
|
||||||
225.用队列实现栈:https://leetcode.cn/problems/implement-stack-using-queues/
|
225.用队列实现栈:https://leetcode.cn/problems/implement-stack-using-queues/
|
||||||
|
|
||||||
347.前K个高频元素:https://leetcode.cn/problems/top-k-frequent-elements/
|
347.前 K 个高频元素:https://leetcode.cn/problems/top-k-frequent-elements/
|
||||||
|
|
||||||
239.滑动窗口最大值:https://leetcode.cn/problems/sliding-window-maximum/
|
239.滑动窗口最大值:https://leetcode.cn/problems/sliding-window-maximum/
|
||||||
|
|
||||||
# 二叉树
|
## 二叉树
|
||||||
|
|
||||||
105.从前序与中序遍历构造二叉树:https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
|
105.从前序与中序遍历构造二叉树:https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
|
||||||
|
|
||||||
117.填充每个节点的下一个右侧节点指针II:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii
|
117.填充每个节点的下一个右侧节点指针 II:https://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii
|
||||||
|
|
||||||
236.二叉树的最近公共祖先:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/
|
236.二叉树的最近公共祖先:https://leetcode.cn/problems/lowest-common-ancestor-of-a-binary-tree/
|
||||||
|
|
||||||
@ -40,10 +47,21 @@
|
|||||||
|
|
||||||
530.二叉搜索树的最小绝对差:https://leetcode.cn/problems/minimum-absolute-difference-in-bst/
|
530.二叉搜索树的最小绝对差:https://leetcode.cn/problems/minimum-absolute-difference-in-bst/
|
||||||
|
|
||||||
# 图
|
## 图
|
||||||
|
|
||||||
200.岛屿数量:https://leetcode.cn/problems/number-of-islands/
|
200.岛屿数量:https://leetcode.cn/problems/number-of-islands/
|
||||||
|
|
||||||
207.课程表:https://leetcode.cn/problems/course-schedule/
|
207.课程表:https://leetcode.cn/problems/course-schedule/
|
||||||
|
|
||||||
210.课程表II:https://leetcode.cn/problems/course-schedule-ii/
|
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,34 +1,40 @@
|
|||||||
---
|
---
|
||||||
|
title: 红黑树
|
||||||
category: 计算机基础
|
category: 计算机基础
|
||||||
tag:
|
tag:
|
||||||
- 数据结构
|
- 数据结构
|
||||||
---
|
---
|
||||||
|
|
||||||
# 红黑树
|
## 红黑树介绍
|
||||||
|
|
||||||
## 红黑树数据结构
|
红黑树(Red Black Tree)是一种自平衡二叉查找树。它是在 1972 年由 Rudolf Bayer 发明的,当时被称为平衡二叉 B 树(symmetric binary B-trees)。后来,在 1978 年被 Leo J. Guibas 和 Robert Sedgewick 修改为如今的“红黑树”。
|
||||||
|
|
||||||
建立在 BST 二叉搜索树的基础上,AVL、2-3树、红黑树都是自平衡二叉树(统称B-树)。但相比于AVL树,高度平衡所带来的时间复杂度,红黑树对平衡的控制要宽松一些,红黑树只需要保证黑色节点平衡即可。
|
由于其自平衡的特性,保证了最坏情形下在 O(logn) 时间复杂度内完成查找、增加、删除等操作,性能表现稳定。
|
||||||
|
|
||||||
|
在 JDK 中,`TreeMap`、`TreeSet` 以及 JDK1.8 的 `HashMap` 底层都用到了红黑树。
|
||||||
|
|
||||||
|
## 为什么需要红黑树?
|
||||||
|
|
||||||
|
红黑树的诞生就是为了解决二叉查找树的缺陷。
|
||||||
|
|
||||||
|
二叉查找树是一种基于比较的数据结构,它的每个节点都有一个键值,而且左子节点的键值小于父节点的键值,右子节点的键值大于父节点的键值。这样的结构可以方便地进行查找、插入和删除操作,因为只需要比较节点的键值就可以确定目标节点的位置。但是,二叉查找树有一个很大的问题,就是它的形状取决于节点插入的顺序。如果节点是按照升序或降序的方式插入的,那么二叉查找树就会退化成一个线性结构,也就是一个链表。这样的情况下,二叉查找树的性能就会大大降低,时间复杂度就会从 O(logn) 变为 O(n)。
|
||||||
|
|
||||||
|
红黑树的诞生就是为了解决二叉查找树的缺陷,因为二叉查找树在某些情况下会退化成一个线性结构。
|
||||||
|
|
||||||
## **红黑树特点**
|
## **红黑树特点**
|
||||||
|
|
||||||
1. 每个节点非红即黑;
|
1. 每个节点非红即黑。黑色决定平衡,红色不决定平衡。这对应了 2-3 树中一个节点内可以存放 1~2 个节点。
|
||||||
|
2. 根节点总是黑色的。
|
||||||
|
3. 每个叶子节点都是黑色的空节点(NIL 节点)。这里指的是红黑树都会有一个空的叶子节点,是红黑树自己的规则。
|
||||||
|
4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定)。通常这条规则也叫不会有连续的红色节点。一个节点最多临时会有 3 个节点,中间是黑色节点,左右是红色节点。
|
||||||
|
5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。每一层都只是有一个节点贡献了树高决定平衡性,也就是对应红黑树中的黑色节点。
|
||||||
|
|
||||||
黑色决定平衡,红色不决定平衡。这对应了2-3树中一个节点内可以存放1~2个节点。
|
正是这些特点才保证了红黑树的平衡,让红黑树的高度不会超过 2log(n+1)。
|
||||||
|
|
||||||
2. 根节点总是黑色的;
|
|
||||||
|
|
||||||
3. 每个叶子节点都是黑色的空节点(NIL 节点);
|
## 红黑树数据结构
|
||||||
|
|
||||||
这里指的是红黑树都会有一个空的叶子节点,是红黑树自己的规则。
|
建立在 BST 二叉搜索树的基础上,AVL、2-3 树、红黑树都是自平衡二叉树(统称 B-树)。但相比于 AVL 树,高度平衡所带来的时间复杂度,红黑树对平衡的控制要宽松一些,红黑树只需要保证黑色节点平衡即可。
|
||||||
|
|
||||||
4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定);
|
|
||||||
|
|
||||||
通常这条规则也叫不会有连续的红色节点。一个节点最多临时会有3个节点,中间是黑色节点,左右是红色节点。
|
|
||||||
|
|
||||||
5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。
|
|
||||||
|
|
||||||
每一层都只是有一个节点贡献了树高决定平衡性,也就是对应红黑树中的黑色节点。
|
|
||||||
|
|
||||||
## 红黑树结构实现
|
## 红黑树结构实现
|
||||||
|
|
||||||
@ -62,28 +68,27 @@ public class Node {
|
|||||||
|
|
||||||
### 3.左旋调衡
|
### 3.左旋调衡
|
||||||
|
|
||||||
#### 3.1一次左旋
|
#### 3.1 一次左旋
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### 3.2右旋+左旋
|
#### 3.2 右旋+左旋
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
### 4.右旋调衡
|
### 4.右旋调衡
|
||||||
|
|
||||||
#### 4.1一次右旋
|
#### 4.1 一次右旋
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
#### 4.2左旋+右旋
|
#### 4.2 左旋+右旋
|
||||||
|
|
||||||

|

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