mirror of
https://github.com/krahets/hello-algo.git
synced 2024-12-25 13:26:30 +08:00
Add the figure of assembling blocks.
Update some texts.
This commit is contained in:
parent
8247a611d7
commit
e35e2e31eb
5 changed files with 7 additions and 5 deletions
|
@ -7,8 +7,7 @@ Author: Krahets (krahets@163.com)
|
||||||
|
|
||||||
def binary_search_left_edge(nums: list[int], target: int) -> int:
|
def binary_search_left_edge(nums: list[int], target: int) -> int:
|
||||||
"""二分查找最左一个元素"""
|
"""二分查找最左一个元素"""
|
||||||
# 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
i, j = 0, len(nums) - 1 # 初始化双闭区间 [0, n-1]
|
||||||
i, j = 0, len(nums) - 1
|
|
||||||
while i <= j:
|
while i <= j:
|
||||||
m = (i + j) // 2 # 计算中点索引 m
|
m = (i + j) // 2 # 计算中点索引 m
|
||||||
if nums[m] < target:
|
if nums[m] < target:
|
||||||
|
@ -24,8 +23,7 @@ def binary_search_left_edge(nums: list[int], target: int) -> int:
|
||||||
|
|
||||||
def binary_search_right_edge(nums: list[int], target: int) -> int:
|
def binary_search_right_edge(nums: list[int], target: int) -> int:
|
||||||
"""二分查找最右一个元素"""
|
"""二分查找最右一个元素"""
|
||||||
# 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素
|
i, j = 0, len(nums) - 1 # 初始化双闭区间 [0, n-1]
|
||||||
i, j = 0, len(nums) - 1
|
|
||||||
while i <= j:
|
while i <= j:
|
||||||
m = (i + j) // 2 # 计算中点索引 m
|
m = (i + j) // 2 # 计算中点索引 m
|
||||||
if nums[m] < target:
|
if nums[m] < target:
|
||||||
|
|
|
@ -58,6 +58,8 @@
|
||||||
|
|
||||||
不修改 `P.next` 也可以。从该链表的角度看,从头结点遍历到尾结点已经遇不到 `P` 了。这意味着结点 `P` 已经从链表中删除了,此时结点 `P` 指向哪里都不会对这条链表产生影响了。
|
不修改 `P.next` 也可以。从该链表的角度看,从头结点遍历到尾结点已经遇不到 `P` 了。这意味着结点 `P` 已经从链表中删除了,此时结点 `P` 指向哪里都不会对这条链表产生影响了。
|
||||||
|
|
||||||
|
从垃圾回收的角度看,对于 Java, Python, Go 等拥有自动垃圾回收的语言来说,节点 `P` 是否被回收取决于是否有仍存在指向它的引用,而不是 `P.next` 的值。在 C, C++ 等语言中,我们需要手动释放节点内存。
|
||||||
|
|
||||||
!!! question "在链表中插入和删除操作的时间复杂度是 $O(1)$ 。但是增删之前都需要 $O(n)$ 查找元素,那为什么时间复杂度不是 $O(n)$ 呢?"
|
!!! question "在链表中插入和删除操作的时间复杂度是 $O(1)$ 。但是增删之前都需要 $O(n)$ 查找元素,那为什么时间复杂度不是 $O(n)$ 呢?"
|
||||||
|
|
||||||
如果是先查找元素、再删除元素,确实是 $O(n)$ 。然而,链表的 $O(1)$ 增删的优势可以在其他应用上得到体现。例如,双向队列适合使用链表实现,我们维护一个指针变量始终指向头结点、尾结点,每次插入与删除操作都是 $O(1)$ 。
|
如果是先查找元素、再删除元素,确实是 $O(n)$ 。然而,链表的 $O(1)$ 增删的优势可以在其他应用上得到体现。例如,双向队列适合使用链表实现,我们维护一个指针变量始终指向头结点、尾结点,每次插入与删除操作都是 $O(1)$ 。
|
||||||
|
|
Binary file not shown.
After Width: | Height: | Size: 95 KiB |
|
@ -8,6 +8,8 @@
|
||||||
|
|
||||||
从数据结构与算法的角度来看,积木的各种形状和连接方式代表数据结构,而组装说明书上的一系列步骤则是算法。
|
从数据结构与算法的角度来看,积木的各种形状和连接方式代表数据结构,而组装说明书上的一系列步骤则是算法。
|
||||||
|
|
||||||
|
![拼装积木](algorithms_are_everywhere.assets/assembling_blocks.jpg)
|
||||||
|
|
||||||
**例二:查阅字典**。在字典里,每个汉字都对应一个拼音,而字典是按照拼音的英文字母顺序排列的。假设我们需要查找一个拼音首字母为 $r$ 的字,通常会这样操作:
|
**例二:查阅字典**。在字典里,每个汉字都对应一个拼音,而字典是按照拼音的英文字母顺序排列的。假设我们需要查找一个拼音首字母为 $r$ 的字,通常会这样操作:
|
||||||
|
|
||||||
1. 翻开字典约一半的页数,查看该页首字母是什么(假设为 $m$ );
|
1. 翻开字典约一半的页数,查看该页首字母是什么(假设为 $m$ );
|
||||||
|
|
|
@ -2,7 +2,7 @@
|
||||||
|
|
||||||
!!! tip
|
!!! tip
|
||||||
|
|
||||||
阅读本节前,请确保已完成堆章节的学习。
|
阅读本节前,请确保已学完「堆」章节。
|
||||||
|
|
||||||
「堆排序 Heap Sort」是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”实现堆排序:
|
「堆排序 Heap Sort」是一种基于堆数据结构实现的高效排序算法。我们可以利用已经学过的“建堆操作”和“元素出堆操作”实现堆排序:
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue