Bug fixes and improvements (#1627)

* Update Copyright 2024 to 2025.

* Fix the flex of .profile-cell for mobile devices.

* Update performance_evaluation.md

* 抛出 -> 给出

* Sync zh and zh-hant version.

* Improve the landing page of the English version.

* Bug fixes

* Fix readme-typing-svg

* Update readme-typing-svg

* Bug fixes

* sync zh and zh-hant versions.
This commit is contained in:
Yudong Jin 2025-01-21 20:00:58 +08:00 committed by GitHub
parent 5dc9dd879c
commit ac0da11157
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
17 changed files with 112 additions and 79 deletions

View File

@ -24,7 +24,7 @@
## 理论估算
由于实际测试具有较大的局限性,因此我们可以考虑仅通过一些计算来评估算法的效率。这种估算方法被称为<u>渐近复杂度分析asymptotic complexity analysis</u>,简称<u>复杂度分析</u>
由于实际测试具有较大的局限性,我们可以考虑仅通过一些计算来评估算法的效率。这种估算方法被称为<u>渐近复杂度分析asymptotic complexity analysis</u>,简称<u>复杂度分析</u>
复杂度分析能够体现算法运行所需的时间和空间资源与输入数据大小之间的关系。**它描述了随着输入数据大小的增加,算法执行所需时间和空间的增长趋势**。这个定义有些拗口,我们可以将其分为三个重点来理解。

View File

@ -52,7 +52,7 @@ index = hash(key) % capacity
观察发现,每种哈希算法的最后一步都是对大质数 $1000000007$ 取模,以确保哈希值在合适的范围内。值得思考的是,为什么要强调对质数取模,或者说对合数取模的弊端是什么?这是一个有趣的问题。
出结论:**使用大质数作为模数,可以最大化地保证哈希值的均匀分布**。因为质数不与其他数字存在公约数,可以减少因取模操作而产生的周期性模式,从而避免哈希冲突。
出结论:**使用大质数作为模数,可以最大化地保证哈希值的均匀分布**。因为质数不与其他数字存在公约数,可以减少因取模操作而产生的周期性模式,从而避免哈希冲突。
举个例子,假设我们选择合数 $9$ 作为模数,它可以被 $3$ 整除,那么所有可以被 $3$ 整除的 `key` 都会被映射到 $0$、$3$、$6$ 这三个哈希值。

View File

@ -349,7 +349,7 @@
<h3>贡献者</h3>
<p>本书在开源社区一百多位贡献者的共同努力下不断完善,感谢他们付出的时间与精力!</p>
<a href="https://github.com/krahets/hello-algo/graphs/contributors">
<img src="https://contrib.rocks/image?repo=krahets/hello-algo&max=300&columns=16" alt="Contributors" style="width: 100%; max-width: 38.5em;">
<img src="https://contrib.rocks/image?repo=krahets/hello-algo&max=300&columns=12" alt="Contributors" style="width: 100%; max-width: 38.5em;">
</a>
</div>
</div>

View File

@ -69,7 +69,7 @@ class LinkedListDeque:
val: int = self._front.val # Temporarily store the head node value
# Remove head node
fnext: ListNode | None = self._front.next
if fnext != None:
if fnext is not None:
fnext.prev = None
self._front.next = None
self._front = fnext # Update head node
@ -78,7 +78,7 @@ class LinkedListDeque:
val: int = self._rear.val # Temporarily store the tail node value
# Remove tail node
rprev: ListNode | None = self._rear.prev
if rprev != None:
if rprev is not None:
rprev.next = None
self._rear.prev = None
self._rear = rprev # Update tail node

View File

@ -7,15 +7,15 @@
<img src="../assets/hero/links.png" alt="" style="position: absolute; width: auto; height: 78.751%; left: 10.545%; top: 7.326%;">
<a href="chapter_introduction/">
<img src="../assets/hero/astronaut.png" alt="" style="height: 46.673%; left: 35.413%; top: 24.343%;">
<span style="left: 52.744%; top: 22.319%;">Encounter with Algorithms</span>
<span style="left: 52.744%; top: 22.319%;">Encounter with Algos</span>
</a>
<a href="chapter_computational_complexity/">
<img src="../assets/hero/chapter_computational_complexity.png" alt="" style="height: 12.347%; left: 36.267%; top: 37.653%;">
<span style="left: 40.244%; top: 33.919%;">Complexity analysis</span>
<span style="left: 36.244%; top: 34.919%;">Complexity analysis</span>
</a>
<a href="chapter_array_and_linkedlist/">
<img src="../assets/hero/chapter_array_and_linkedlist.png" alt="" style="height: 22.242%; left: 73.242%; top: 52.481%;">
<span style="left: 90.897%; top: 76.259%;">Array and linked list</span>
<span style="left: 85.897%; top: 76.259%;">Array and linked list</span>
</a>
<a href="chapter_stack_and_queue/">
<img src="../assets/hero/chapter_stack_and_queue.png" alt="" style="height: 14.302%; left: 62.646%; top: 77.875%;">
@ -23,7 +23,7 @@
</a>
<a href="chapter_hashing/">
<img src="../assets/hero/chapter_hashing.png" alt="" style="height: 15.266%; left: 63.281%; top: 27.933%;">
<span style="left: 68.862%; top: 46.292%;">Hash table</span>
<span style="left: 68.862%; top: 45.792%;">Hash table</span>
</a>
<a href="chapter_tree/">
<img src="../assets/hero/chapter_tree.png" alt="" style="height: 19.615%; left: 80.137%; top: 26.678%;">
@ -43,7 +43,7 @@
</a>
<a href="chapter_sorting/">
<img src="../assets/hero/chapter_sorting.png" alt="" style="height: 9.574%; left: 25.409%; top: 40.747%;">
<span style="left: 28.805%; top: 53.808%;">Sorting</span>
<span style="left: 28.805%; top: 53.308%;">Sorting</span>
</a>
<a href="chapter_divide_and_conquer/">
<img src="../assets/hero/chapter_divide_and_conquer.png" alt="" style="height: 18.681%; left: 32.721%; top: 4.816%;">
@ -51,11 +51,11 @@
</a>
<a href="chapter_backtracking/">
<img src="../assets/hero/chapter_backtracking.png" alt="" style="height: 17.338%; left: 4.875%; top: 32.925%;">
<span style="left: 4.742%; top: 50.113%;">Backtracking</span>
<span style="left: 8.742%; top: 50.113%;">Backtracking</span>
</a>
<a href="chapter_dynamic_programming/">
<img src="../assets/hero/chapter_dynamic_programming.png" alt="" style="height: 15.47%; left: 9.406%; top: 57.472%;">
<span style="left: 8.561%; top: 75.351%;">Dynamic programming</span>
<span style="left: 14.561%; top: 75.351%;">Dynamic programming</span>
</a>
<a href="chapter_greedy/">
<img src="../assets/hero/chapter_greedy.png" alt="" style="height: 14.127%; left: 23.132%; top: 75.803%;">
@ -65,7 +65,7 @@
<!-- heading -->
<div class="heading-div">
<img style="height: min(9vh, 12vw);" src="https://readme-typing-svg.demolab.com?font=Noto+Sans+SC&weight=400&duration=3500&pause=2000&color=21C8B8&center=true&vCenter=true&random=false&width=200&lines=Hello%2C+Algo+!" alt="" />
<img style="height: min(9vh, 12vw);" src="https://readme-typing-svg.demolab.com/?font=Roboto&weight=400&duration=3500&pause=2000&color=FFF&center=true&vCenter=true&random=false&width=200&lines=Hello%2C+Algo!" alt="" />
<div style="pointer-events: auto;">
<p style="margin-top: max(-1vh, -2vw); margin-bottom: min(2vh, 3.5vw);">
Data structures and algorithms crash course with animated illustrations and off-the-shelf code
@ -113,7 +113,7 @@
<img src="https://img.shields.io/badge/Dart-snow?logo=dart&logoColor=0175C2" alt="" />
<img src="https://img.shields.io/badge/Zig-snow?logo=zig&logoColor=F7A41D" alt="" />
</div>
<p style="margin-top: 2em;">500 animated illustrations, 14 programming languages, and 3000 community Q&As to help you quickly get started with data structures and algorithms</p>
<p style="margin-top: 2em;">500 animated illustrations, 14 programming languages, and 3000 community Q&As to help you dive into data structures and algorithms.</p>
</div>
</section>
@ -144,7 +144,7 @@
<img class="device-on-hover" style="height: 66.31%;" src="../assets/hero/web_mac_iphone.png" alt="">
<div style="height: 4.34%;"></div>
<div class="text-button">
<span>Read online</span>
<span>Web</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z" />
</svg>
@ -155,7 +155,7 @@
<a href="https://github.com/krahets/hello-algo/releases">
<img class="device-on-hover" style="height: 75%;" src="../assets/hero/pdf_ipad.png" alt="">
<div class="text-button">
<span>Download PDF</span>
<span>PDF</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z" />
</svg>
@ -195,7 +195,7 @@
</svg>
<h3 style="margin-left: 0.5em;">Animated illustrations</h3>
</div>
<p style="margin: 0;">It's crafted for ease of understanding, ensuring a smooth learning journey.</p>
<p style="margin: 0;">Its crafted for a smooth learning experience.</p>
<p class="intro-quote">"A picture is worth a thousand words."</p>
</div>
</div>
@ -212,7 +212,7 @@
</svg>
<h3 style="margin-left: 0.5em;">Off-the-shelf code</h3>
</div>
<p style="margin: 0;">Featuring multiple programming languages, all runnable with a single click.</p>
<p style="margin: 0;">One click to run code in multiple languages.</p>
<p class="intro-quote">"Talk is cheap. Show me the code."</p>
</div>
</div>
@ -227,7 +227,7 @@
</svg>
<h3 style="margin-left: 0.5em;">Learning together</h3>
</div>
<p style="margin: 0;">Welcome discussions and questions with open arms.</p>
<p style="margin: 0;">Dont hesitate to ask or share your thoughts.</p>
<p class="intro-quote">"Learning by teaching."</p>
</div>
</div>
@ -416,7 +416,7 @@
<h3>Contributors</h3>
<p>This book has been refined by the efforts of over 180 contributors. We sincerely thank them for their invaluable time and contributions!</p>
<a href="https://github.com/krahets/hello-algo/graphs/contributors">
<img src="https://contrib.rocks/image?repo=krahets/hello-algo&max=300&columns=16" alt="Contributors" style="width: 100%; max-width: 38.5em;">
<img src="https://contrib.rocks/image?repo=krahets/hello-algo&max=300&columns=12" alt="Contributors" style="width: 100%; max-width: 38.5em;">
</a>
</div>
</div>

View File

@ -12,7 +12,7 @@ edit_uri: tree/main/docs
version: 1.2.0
# Copyright
copyright: Copyright &copy; 2024 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
copyright: Copyright &copy; 2025 krahets<br>The website content is licensed under <a href="https://creativecommons.org/licenses/by-nc-sa/4.0/">CC BY-NC-SA 4.0</a>
# Configuration
theme:

View File

@ -1,7 +1,7 @@
/* Color Settings */
/* https://github.com/squidfunk/mkdocs-material/blob/6b5035f5580f97532d664e3d1babf5f320e88ee9/src/assets/stylesheets/main/_colors.scss */
/* https://squidfunk.github.io/mkdocs-material/setup/changing-the-colors/#custom-colors */
:root > * {
:root>* {
--md-primary-fg-color: #ffffff;
--md-primary-bg-color: #1d1d20;
@ -69,8 +69,10 @@
.md-header--landing {
box-shadow: none;
transition: none;
backdrop-filter: saturate(180%) blur(20px); /* Gaussian blur */
-webkit-backdrop-filter: saturate(180%) blur(20px); /* Safari */
backdrop-filter: saturate(180%) blur(20px);
/* Gaussian blur */
-webkit-backdrop-filter: saturate(180%) blur(20px);
/* Safari */
background-color: var(--md-header-bg-color);
}
@ -159,7 +161,7 @@ body {
/* max height of code block */
/* https://github.com/squidfunk/mkdocs-material/issues/3444 */
.md-typeset pre > code {
.md-typeset pre>code {
max-height: 25rem;
}
@ -176,7 +178,8 @@ body {
align-items: center;
justify-content: center;
margin: 0 auto;
width: 100%; /* Default to full width */
width: 100%;
/* Default to full width */
}
/* Admonition for python tutor */
@ -192,12 +195,13 @@ body {
box-shadow: var(--md-shadow-z1);
}
.md-typeset .pythontutor > .admonition-title,
.md-typeset .pythontutor > summary {
.md-typeset .pythontutor>.admonition-title,
.md-typeset .pythontutor>summary {
background-color: var(--md-code-bg-color);
}
.md-typeset .pythontutor > .admonition-title::before,
.md-typeset .pythontutor > summary::before {
.md-typeset .pythontutor>.admonition-title::before,
.md-typeset .pythontutor>summary::before {
background-color: rgb(55, 118, 171);
-webkit-mask-image: var(--md-admonition-icon--pythontutor);
mask-image: var(--md-admonition-icon--pythontutor);
@ -301,7 +305,7 @@ body {
a:hover .device-on-hover {
filter: drop-shadow(0 0 0.2rem rgba(0, 0, 0, 0.15));
transform: scale(1.02);
transform: scale(1.01);
}
/* text button */
@ -363,27 +367,27 @@ a:hover .text-button span {
}
/* hover on the planets */
.hero-div > a > img {
.hero-div>a>img {
width: auto;
position: absolute;
transition: transform 0.3s ease-in-out, filter 0.3s ease-in-out;
}
.hero-div > a > span {
.hero-div>a>span {
margin: 0;
position: absolute;
transform: translateX(-50%) translateY(-50%);
white-space: nowrap; /* prevent line breaks */
white-space: nowrap;
/* prevent line breaks */
color: white;
}
.hero-div > a:hover > img {
filter: brightness(1.15) saturate(1.1)
drop-shadow(0 0 0.5rem rgba(255, 255, 255, 0.2));
.hero-div>a:hover>img {
filter: brightness(1.15) saturate(1.1) drop-shadow(0 0 0.5rem rgba(255, 255, 255, 0.2));
transform: scale(1.03);
}
.hero-div > a:hover > span {
.hero-div>a:hover>span {
text-decoration: underline;
color: var(--md-typeset-btn-color);
}
@ -420,13 +424,14 @@ a:hover .text-button span {
.intro-image {
flex-shrink: 0;
flex-grow: 0;
width: 55%;
width: 50%;
border-radius: 0.5em;
box-shadow: var(--md-shadow-z2);
}
.intro-text {
flex-grow: 1; /* fill the space */
flex-grow: 1;
/* fill the space */
display: flex;
flex-direction: column;
justify-content: center;
@ -436,7 +441,7 @@ a:hover .text-button span {
margin: 2em;
}
.intro-text > div {
.intro-text>div {
align-self: flex-start;
width: auto;
margin: 0 auto;
@ -461,9 +466,8 @@ a:hover .text-button span {
}
.profile-cell {
flex: 1; /* even distribution */
flex-basis: 20%;
margin: 1em 0.5em;
flex: 1 1 15%;
margin: 1em 0;
text-align: center;
}
@ -494,12 +498,16 @@ a:hover .text-button span {
}
}
/* Hide table of contents */
/* mobile devices */
@media screen and (max-width: 60em) {
.home-div {
font-size: 0.75rem;
}
.hero-div {
margin-top: -4rem;
}
.intro-container {
flex-direction: column;
}
@ -524,11 +532,16 @@ a:hover .text-button span {
.text-button {
margin: 0.7em auto;
}
.profile-cell {
flex: 1 1 30%;
}
}
.video-container {
position: relative;
padding-bottom: 56.25%; /* 16:9 */
padding-bottom: 56.25%;
/* 16:9 */
height: 0;
}

View File

@ -69,7 +69,7 @@ class LinkedListDeque:
val: int = self._front.val # 暫存頭節點值
# 刪除頭節點
fnext: ListNode | None = self._front.next
if fnext != None:
if fnext is not None:
fnext.prev = None
self._front.next = None
self._front = fnext # 更新頭節點
@ -78,7 +78,7 @@ class LinkedListDeque:
val: int = self._rear.val # 暫存尾節點值
# 刪除尾節點
rprev: ListNode | None = self._rear.prev
if rprev != None:
if rprev is not None:
rprev.next = None
self._rear.prev = None
self._rear = rprev # 更新尾節點

View File

@ -21,9 +21,8 @@ fn extend(nums: &[i32], enlarge: usize) -> Vec<i32> {
// 初始化一個擴展長度後的陣列
let mut res: Vec<i32> = vec![0; nums.len() + enlarge];
// 將原陣列中的所有元素複製到新
for i in 0..nums.len() {
res[i] = nums[i];
}
res[0..nums.len()].copy_from_slice(nums);
// 返回擴展後的新陣列
res
}
@ -54,7 +53,8 @@ fn traverse(nums: &[i32]) {
_count += nums[i];
}
// 直接走訪陣列元素
for num in nums {
_count = 0;
for &num in nums {
_count += num;
}
}

View File

@ -19,9 +19,6 @@ pub fn insert<T>(n0: &Rc<RefCell<ListNode<T>>>, P: Rc<RefCell<ListNode<T>>>) {
/* 刪除鏈結串列的節點 n0 之後的首個節點 */
#[allow(non_snake_case)]
pub fn remove<T>(n0: &Rc<RefCell<ListNode<T>>>) {
if n0.borrow().next.is_none() {
return;
};
// n0 -> P -> n1
let P = n0.borrow_mut().next.take();
if let Some(node) = P {
@ -31,26 +28,39 @@ pub fn remove<T>(n0: &Rc<RefCell<ListNode<T>>>) {
}
/* 訪問鏈結串列中索引為 index 的節點 */
pub fn access<T>(head: Rc<RefCell<ListNode<T>>>, index: i32) -> Rc<RefCell<ListNode<T>>> {
pub fn access<T>(head: Rc<RefCell<ListNode<T>>>, index: i32) -> Option<Rc<RefCell<ListNode<T>>>> {
fn dfs<T>(
head: Option<&Rc<RefCell<ListNode<T>>>>,
index: i32,
) -> Option<Rc<RefCell<ListNode<T>>>> {
if index <= 0 {
return head;
};
if let Some(node) = &head.borrow().next {
return access(node.clone(), index - 1);
return head.cloned();
}
return head;
if let Some(node) = head {
dfs(node.borrow().next.as_ref(), index - 1)
} else {
None
}
}
dfs(Some(head).as_ref(), index)
}
/* 在鏈結串列中查詢值為 target 的首個節點 */
pub fn find<T: PartialEq>(head: Rc<RefCell<ListNode<T>>>, target: T, index: i32) -> i32 {
if head.borrow().val == target {
return index;
};
if let Some(node) = &head.borrow_mut().next {
return find(node.clone(), target, index + 1);
pub fn find<T: PartialEq>(head: Rc<RefCell<ListNode<T>>>, target: T) -> i32 {
fn find<T: PartialEq>(head: Option<&Rc<RefCell<ListNode<T>>>>, target: T, idx: i32) -> i32 {
if let Some(node) = head {
if node.borrow().val == target {
return idx;
}
return -1;
return find(node.borrow().next.as_ref(), target, idx + 1);
} else {
-1
}
}
find(Some(head).as_ref(), target, 0)
}
/* Driver Code */
@ -82,9 +92,9 @@ fn main() {
/* 訪問節點 */
let node = access(n0.clone(), 3);
println!("鏈結串列中索引 3 處的節點的值 = {}", node.borrow().val);
println!("鏈結串列中索引 3 處的節點的值 = {}", node.unwrap().borrow().val);
/* 查詢節點 */
let index = find(n0.clone(), 2, 0);
let index = find(n0.clone(), 2);
println!("鏈結串列中值為 2 的節點的索引 = {}", index);
}

View File

@ -10,9 +10,15 @@ pub struct Vertex {
pub val: i32,
}
impl From<i32> for Vertex {
fn from(value: i32) -> Self {
Self { val: value }
}
}
/* 輸入值串列 vals ,返回頂點串列 vets */
pub fn vals_to_vets(vals: Vec<i32>) -> Vec<Vertex> {
vals.into_iter().map(|val| Vertex { val }).collect()
vals.into_iter().map(|val| val.into()).collect()
}
/* 輸入頂點串列 vets ,返回值串列 vals */

View File

@ -24,7 +24,7 @@
## 理論估算
由於實際測試具有較大的侷限性,因此我們可以考慮僅透過一些計算來評估演算法的效率。這種估算方法被稱為<u>漸近複雜度分析asymptotic complexity analysis</u>,簡稱<u>複雜度分析</u>
由於實際測試具有較大的侷限性,我們可以考慮僅透過一些計算來評估演算法的效率。這種估算方法被稱為<u>漸近複雜度分析asymptotic complexity analysis</u>,簡稱<u>複雜度分析</u>
複雜度分析能夠體現演算法執行所需的時間和空間資源與輸入資料大小之間的關係。**它描述了隨著輸入資料大小的增加,演算法執行所需時間和空間的增長趨勢**。這個定義有些拗口,我們可以將其分為三個重點來理解。

View File

@ -110,7 +110,7 @@ $$
![暴力搜尋遞迴樹](dp_solution_pipeline.assets/min_path_sum_dfs.png)
每個狀態都有向下和向右兩種選擇,從左上角走到右下角總共需要 $m + n - 2$ 步,所以最差時間複雜度為 $O(2^{m + n})$ 。請注意,這種計算方式未考慮臨近網格邊界的情況,當到達網路邊界時只剩下一種選擇,因此實際的路徑數量會少一些。
每個狀態都有向下和向右兩種選擇,從左上角走到右下角總共需要 $m + n - 2$ 步,所以最差時間複雜度為 $O(2^{m + n})$ ,其中 $n$ 和 $m$ 分別為網格的行數和列數。請注意,這種計算方式未考慮臨近網格邊界的情況,當到達網路邊界時只剩下一種選擇,因此實際的路徑數量會少一些。
### 方法二:記憶化搜尋

View File

@ -52,7 +52,7 @@ index = hash(key) % capacity
觀察發現,每種雜湊演算法的最後一步都是對大質數 $1000000007$ 取模,以確保雜湊值在合適的範圍內。值得思考的是,為什麼要強調對質數取模,或者說對合數取模的弊端是什麼?這是一個有趣的問題。
結論:**使用大質數作為模數,可以最大化地保證雜湊值的均勻分佈**。因為質數不與其他數字存在公約數,可以減少因取模操作而產生的週期性模式,從而避免雜湊衝突。
給出結論:**使用大質數作為模數,可以最大化地保證雜湊值的均勻分佈**。因為質數不與其他數字存在公約數,可以減少因取模操作而產生的週期性模式,從而避免雜湊衝突。
舉個例子,假設我們選擇合數 $9$ 作為模數,它可以被 $3$ 整除,那麼所有可以被 $3$ 整除的 `key` 都會被對映到 $0$、$3$、$6$ 這三個雜湊值。

View File

@ -2,7 +2,7 @@
!!! tip
閱讀本節前,請確保已學完“堆積章節。
閱讀本節前,請確保已學完“堆積章節。
<u>堆積排序heap sort</u>是一種基於堆積資料結構實現的高效排序演算法。我們可以利用已經學過的“建堆積操作”和“元素出堆積操作”實現堆積排序。

View File

@ -493,6 +493,8 @@
P->left = n2;
// 刪除節點 P
n1->left = n2;
// 釋放記憶體
delete P;
```
=== "Java"
@ -598,6 +600,8 @@
P->left = n2;
// 刪除節點 P
n1->left = n2;
// 釋放記憶體
free(P);
```
=== "Kotlin"

View File

@ -131,7 +131,7 @@
<div style="height: 8.17%;"></div>
<img class="device-on-hover" style="height: 66.83%;" src="../assets/hero/cover_render.png" alt="Cover">
<div class="text-button">
<span>紙質書(簡中)</span>
<span>紙質書</span>
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 320 512">
<path d="M278.6 233.4c12.5 12.5 12.5 32.8 0 45.3l-160 160c-12.5 12.5-32.8 12.5-45.3 0s-12.5-32.8 0-45.3L210.7 256 73.4 118.6c-12.5-12.5-12.5-32.8 0-45.3s32.8-12.5 45.3 0l160 160z" />
</svg>
@ -368,7 +368,7 @@
<h3>貢獻者</h3>
<p>本書在開源社群一百多位貢獻者的共同努力下不斷完善,感謝他們付出的時間與精力!</p>
<a href="https://github.com/krahets/hello-algo/graphs/contributors">
<img src="https://contrib.rocks/image?repo=krahets/hello-algo&max=300&columns=16" alt="Contributors" style="width: 100%; max-width: 38.5em;">
<img src="https://contrib.rocks/image?repo=krahets/hello-algo&max=300&columns=12" alt="Contributors" style="width: 100%; max-width: 38.5em;">
</a>
</div>
</div>