1
0
mirror of https://github.com/Snailclimb/JavaGuide synced 2025-06-16 18:10:13 +08:00

[docs update]经典LeetCode题目推荐+红黑树内容完善

This commit is contained in:
Guide 2023-11-07 16:25:02 +08:00
parent abaa691ffa
commit a09632f9be
13 changed files with 83 additions and 49 deletions

View File

@ -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",

View File

@ -1,4 +1,9 @@
# 经典算法思想介绍
---
title: 经典算法思想总结含LeetCode题目推荐
category: 计算机基础
tag:
- 算法
---
## 贪心算法
@ -19,11 +24,11 @@
121.买卖股票的最佳时机https://leetcode.cn/problems/best-time-to-buy-and-sell-stock/
122.买卖股票的最佳时机IIhttps://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
122.买卖股票的最佳时机 IIhttps://leetcode.cn/problems/best-time-to-buy-and-sell-stock-ii/
55.跳跃游戏https://leetcode.cn/problems/jump-game/
45.跳跃游戏IIhttps://leetcode.cn/problems/jump-game-ii/
45.跳跃游戏 IIhttps://leetcode.cn/problems/jump-game-ii/
## 动态规划
@ -31,15 +36,15 @@
动态规划中每一个状态一定是由上一个状态推导出来的,这一点就区分于贪心,贪心没有状态推导,而是从局部直接选最优的。
经典题目01背包、完全背包
经典题目01 背包、完全背包
### 一般解题步骤
- 确定dp数组dp table以及下标的含义
- 确定 dp 数组dp table以及下标的含义
- 确定递推公式
- dp数组如何初始化
- dp 数组如何初始化
- 确定遍历顺序
- 举例推导dp数组
- 举例推导 dp 数组
### LeetCode
@ -63,7 +68,7 @@
件时,就“回溯”返回,尝试别的路径。其本质就是穷举。
经典题目8皇后
经典题目8 皇后
### 一般解题步骤
@ -77,19 +82,19 @@
39.组合总和https://leetcode.cn/problems/combination-sum/
40.组合总和IIhttps://leetcode.cn/problems/combination-sum-ii/
40.组合总和 IIhttps://leetcode.cn/problems/combination-sum-ii/
78.子集https://leetcode.cn/problems/subsets/
90.子集IIhttps://leetcode.cn/problems/subsets-ii/
90.子集 IIhttps://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/
23.合并k个升序链表https://leetcode.cn/problems/merge-k-sorted-lists/
23.合并 k 个升序链表https://leetcode.cn/problems/merge-k-sorted-lists/

View File

@ -1,36 +1,43 @@
# 数组
---
title: 常见数据结构经典LeetCode题目推荐
category: 计算机基础
tag:
- 算法
---
## 数组
704.二分查找https://leetcode.cn/problems/binary-search/
80.删除有序数组中的重复项IIhttps://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii
80.删除有序数组中的重复项 IIhttps://leetcode.cn/problems/remove-duplicates-from-sorted-array-ii
977.有序数组的平方https://leetcode.cn/problems/squares-of-a-sorted-array/
# 链表
## 链表
707.设计链表https://leetcode.cn/problems/design-linked-list/
206.反转链表https://leetcode.cn/problems/reverse-linked-list/
92.反转链表IIhttps://leetcode.cn/problems/reverse-linked-list-ii/
92.反转链表 IIhttps://leetcode.cn/problems/reverse-linked-list-ii/
61.旋转链表https://leetcode.cn/problems/rotate-list/
# 栈与队列
## 栈与队列
232.用栈实现队列https://leetcode.cn/problems/implement-queue-using-stacks/
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/
# 二叉树
## 二叉树
105.从前序与中序遍历构造二叉树https://leetcode.cn/problems/construct-binary-tree-from-preorder-and-inorder-traversal/
117.填充每个节点的下一个右侧节点指针IIhttps://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii
117.填充每个节点的下一个右侧节点指针 IIhttps://leetcode.cn/problems/populating-next-right-pointers-in-each-node-ii
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/
# 图
## 图
200.岛屿数量https://leetcode.cn/problems/number-of-islands/
207.课程表https://leetcode.cn/problems/course-schedule/
210.课程表IIhttps://leetcode.cn/problems/course-schedule-ii/
210.课程表 IIhttps://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/

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 26 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 22 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 30 KiB

After

Width:  |  Height:  |  Size: 13 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 25 KiB

After

Width:  |  Height:  |  Size: 11 KiB

View File

@ -1,34 +1,40 @@
---
title: 红黑树
category: 计算机基础
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 节点);
## 红黑树数据结构
这里指的是红黑树都会有一个空的叶子节点,是红黑树自己的规则。
4. 如果节点是红色的,则它的子节点必须是黑色的(反之不一定);
通常这条规则也叫不会有连续的红色节点。一个节点最多临时会有3个节点中间是黑色节点左右是红色节点。
5. 从根节点到叶节点或空子节点的每条路径,必须包含相同数目的黑色节点(即相同的黑色高度)。
每一层都只是有一个节点贡献了树高决定平衡性,也就是对应红黑树中的黑色节点。
建立在 BST 二叉搜索树的基础上AVL、2-3 树、红黑树都是自平衡二叉树(统称 B-树)。但相比于 AVL 树,高度平衡所带来的时间复杂度,红黑树对平衡的控制要宽松一些,红黑树只需要保证黑色节点平衡即可。
## 红黑树结构实现
@ -62,28 +68,27 @@ public class Node {
### 3.左旋调衡
#### 3.1一次左旋
#### 3.1 一次左旋
![幻灯片3](pictures/红黑树/红黑树3.PNG)
#### 3.2右旋+左旋
#### 3.2 右旋+左旋
![幻灯片4](pictures/红黑树/红黑树4.PNG)
### 4.右旋调衡
#### 4.1一次右旋
#### 4.1 一次右旋
![幻灯片5](pictures/红黑树/红黑树5.PNG)
#### 4.2左旋+右旋
#### 4.2 左旋+右旋
![幻灯片6](pictures/红黑树/红黑树6.PNG)
**红黑树的应用**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 -->

View File

@ -647,7 +647,7 @@ System.out.println(aa==bb);// true
会创建 1 或 2 个字符串对象。
1、如果字符串常量池中不存在字符串对象“abc”的引用那么它将首先在字符串常量池中创建,然后在堆空间中创建,因此将创建总共 2 个字符串对象
1、如果字符串常量池中不存在字符串对象“abc”的引用那么它会在堆上创建两个字符串对象,其中一个字符串对象的引用会被保存在字符串常量池中
示例代码JDK 1.8

View File

@ -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 数据的工具库。

View File

@ -176,7 +176,7 @@ Kafka、Dubbo、ZooKeeper、Netty、Caffeine、Akka 中都有对时间轮的实
![](https://oss.javaguide.cn/github/javaguide/system-design/schedule-task/three-layers-of-time-wheel.png)
上图的时间轮,第 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 层。