Several bug fixes and improvements (#945)

* Update Dockerfile for code debugging.

* Format Python code using Black.

* Improve dark theme by defining html classes for the figures, animations and cover images.

* Fix several glossary translation.

* Update a code comment.

* Fix climbing_stairs_backtrack: the pruning should not require the sorted choices list.

* Update the code of array and list traversal.

* Fix a rendering issue of README.md

* Update code of list traversal.

* Fix array_definition.png

* Update README.md

* Fix max_capacity_moving_short_board.png

* Fix array.dart

* Fix array.dart

* Fix array.dart

* Fix array.dart
This commit is contained in:
Yudong Jin 2023-11-14 21:27:35 +08:00 committed by GitHub
parent 9baf4a1753
commit fcbaf101a4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
64 changed files with 212 additions and 218 deletions

View File

@ -1,7 +1,6 @@
<p align="center"> <p align="center">
<a href="https://www.hello-algo.com/"> <a href="https://www.hello-algo.com/">
<img src="https://www.hello-algo.com/index.assets/hello_algo_header.png" width="450"> <img src="https://www.hello-algo.com/index.assets/hello_algo_header.png" width="450"></a>
</a>
</p> </p>
<p align="center"> <p align="center">
@ -12,11 +11,9 @@
<p align="center"> <p align="center">
<a href="https://www.hello-algo.com/"> <a href="https://www.hello-algo.com/">
<img src="https://www.hello-algo.com/index.assets/btn_read_online_dark.png" width="155"> <img src="https://www.hello-algo.com/index.assets/btn_read_online_dark.png" width="155"></a>
</a>
<a href="https://github.com/krahets/hello-algo/releases"> <a href="https://github.com/krahets/hello-algo/releases">
<img src="https://www.hello-algo.com/index.assets/btn_download_pdf_dark.png" width="155"> <img src="https://www.hello-algo.com/index.assets/btn_download_pdf_dark.png" width="155"></a>
</a>
</p> </p>
<p align="center"> <p align="center">
@ -66,7 +63,7 @@
- [内容修正](https://www.hello-algo.com/chapter_appendix/contribution/):请您协助修正或在评论区指出语法错误、内容缺失、文字歧义、无效链接或代码 bug 等问题。 - [内容修正](https://www.hello-algo.com/chapter_appendix/contribution/):请您协助修正或在评论区指出语法错误、内容缺失、文字歧义、无效链接或代码 bug 等问题。
- [代码转译](https://github.com/krahets/hello-algo/issues/15):期待您贡献各种语言代码,已支持 Python、Java、C++、Go、JavaScript 等 12 门编程语言。 - [代码转译](https://github.com/krahets/hello-algo/issues/15):期待您贡献各种语言代码,已支持 Python、Java、C++、Go、JavaScript 等 12 门编程语言。
- [整书翻译](https://github.com/krahets/hello-algo/tree/en):诚邀您加入我们的中译英小组,成员主要来自计算机相关专业、英语专业和英文母语者。 - [Chinese-to-English](https://github.com/krahets/hello-algo/tree/en):诚邀您加入我们的翻译小组,成员主要来自计算机相关专业、英语专业和英文母语者。
欢迎您提出宝贵意见和建议,如有任何问题请提交 Issues 或微信联系 `krahets-jyd` 欢迎您提出宝贵意见和建议,如有任何问题请提交 Issues 或微信联系 `krahets-jyd`

View File

@ -10,7 +10,7 @@ RUN apt-get update && apt-get install -y wget
# Install languages environment # Install languages environment
ARG LANGS ARG LANGS
RUN for LANG in $LANGS; do \ RUN for LANG in $LANGS; do \
case "$LANG" in \ case $LANG in \
python) \ python) \
apt-get install -y python3.10 && \ apt-get install -y python3.10 && \
update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 ;; \ update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 ;; \

View File

@ -55,7 +55,7 @@ void traverse(int *nums, int size) {
int count = 0; int count = 0;
// 通过索引遍历数组 // 通过索引遍历数组
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
count++; count += nums[i];
} }
} }

View File

@ -16,7 +16,7 @@ void backtrack(int *choices, int state, int n, int *res, int len) {
int choice = choices[i]; int choice = choices[i];
// 剪枝:不允许越过第 n 阶 // 剪枝:不允许越过第 n 阶
if (state + choice > n) if (state + choice > n)
break; continue;
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
backtrack(choices, state + choice, n, res, len); backtrack(choices, state + choice, n, res, len);
// 回退 // 回退

View File

@ -52,7 +52,7 @@ void traverse(int *nums, int size) {
int count = 0; int count = 0;
// 通过索引遍历数组 // 通过索引遍历数组
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
count++; count += nums[i];
} }
} }

View File

@ -14,8 +14,8 @@ int main() {
printVector(nums); printVector(nums);
/* 访问元素 */ /* 访问元素 */
int x = nums[1]; int num = nums[1];
cout << "访问索引 1 处的元素,得到 x = " << x << endl; cout << "访问索引 1 处的元素,得到 num = " << num << endl;
/* 更新元素 */ /* 更新元素 */
nums[1] = 0; nums[1] = 0;
@ -49,13 +49,12 @@ int main() {
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
int count = 0; int count = 0;
for (int i = 0; i < nums.size(); i++) { for (int i = 0; i < nums.size(); i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
for (int n : nums) { for (int x : nums) {
count++; count += x;
} }
/* 拼接两个列表 */ /* 拼接两个列表 */

View File

@ -16,7 +16,7 @@ void backtrack(vector<int> &choices, int state, int n, vector<int> &res) {
for (auto &choice : choices) { for (auto &choice : choices) {
// 剪枝:不允许越过第 n 阶 // 剪枝:不允许越过第 n 阶
if (state + choice > n) if (state + choice > n)
break; continue;
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
backtrack(choices, state + choice, n, res); backtrack(choices, state + choice, n, res);
// 回退 // 回退

View File

@ -50,11 +50,11 @@ public class array {
int count = 0; int count = 0;
// 通过索引遍历数组 // 通过索引遍历数组
for (int i = 0; i < nums.Length; i++) { for (int i = 0; i < nums.Length; i++) {
count++; count += nums[i];
} }
// 直接遍历数组 // 直接遍历数组元素
foreach (int num in nums) { foreach (int num in nums) {
count++; count += num;
} }
} }

View File

@ -46,13 +46,12 @@ public class list {
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
int count = 0; int count = 0;
for (int i = 0; i < nums.Count; i++) { for (int i = 0; i < nums.Count; i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
foreach (int n in nums) { foreach (int x in nums) {
count++; count += x;
} }
/* 拼接两个列表 */ /* 拼接两个列表 */

View File

@ -16,7 +16,7 @@ public class climbing_stairs_backtrack {
foreach (int choice in choices) { foreach (int choice in choices) {
// 剪枝:不允许越过第 n 阶 // 剪枝:不允许越过第 n 阶
if (state + choice > n) if (state + choice > n)
break; continue;
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
Backtrack(choices, state + choice, n, res); Backtrack(choices, state + choice, n, res);
// 回退 // 回退

View File

@ -9,7 +9,7 @@
import 'dart:math'; import 'dart:math';
/* 随机访问元素 */ /* 随机访问元素 */
int randomAccess(List nums) { int randomAccess(List<int> nums) {
// [0, nums.length) // [0, nums.length)
int randomIndex = Random().nextInt(nums.length); int randomIndex = Random().nextInt(nums.length);
// //
@ -18,7 +18,7 @@ int randomAccess(List nums) {
} }
/* 扩展数组长度 */ /* 扩展数组长度 */
List extend(List nums, int enlarge) { List<int> extend(List<int> nums, int enlarge) {
// //
List<int> res = List.filled(nums.length + enlarge, 0); List<int> res = List.filled(nums.length + enlarge, 0);
// //
@ -30,7 +30,7 @@ List extend(List nums, int enlarge) {
} }
/* 在数组的索引 index 处插入元素 num */ /* 在数组的索引 index 处插入元素 num */
void insert(List nums, int num, int index) { void insert(List<int> nums, int num, int index) {
// index // index
for (var i = nums.length - 1; i > index; i--) { for (var i = nums.length - 1; i > index; i--) {
nums[i] = nums[i - 1]; nums[i] = nums[i - 1];
@ -40,7 +40,7 @@ void insert(List nums, int num, int index) {
} }
/* 删除索引 index 处元素 */ /* 删除索引 index 处元素 */
void remove(List nums, int index) { void remove(List<int> nums, int index) {
// index // index
for (var i = index; i < nums.length - 1; i++) { for (var i = index; i < nums.length - 1; i++) {
nums[i] = nums[i + 1]; nums[i] = nums[i + 1];
@ -48,24 +48,24 @@ void remove(List nums, int index) {
} }
/* 遍历数组元素 */ /* 遍历数组元素 */
void traverse(List nums) { void traverse(List<int> nums) {
var count = 0; int count = 0;
// //
for (var i = 0; i < nums.length; i++) { for (var i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
// //
for (var num in nums) { for (int num in nums) {
count++; count += num;
} }
// forEach // forEach
nums.forEach((element) { nums.forEach((num) {
count++; count += num;
}); });
} }
/* 在数组中查找指定元素 */ /* 在数组中查找指定元素 */
int find(List nums, int target) { int find(List<int> nums, int target) {
for (var i = 0; i < nums.length; i++) { for (var i = 0; i < nums.length; i++) {
if (nums[i] == target) return i; if (nums[i] == target) return i;
} }
@ -77,7 +77,7 @@ void main() {
/* 初始化数组 */ /* 初始化数组 */
var arr = List.filled(5, 0); var arr = List.filled(5, 0);
print('数组 arr = $arr'); print('数组 arr = $arr');
List nums = [1, 3, 2, 5, 4]; List<int> nums = [1, 3, 2, 5, 4];
print('数组 nums = $nums'); print('数组 nums = $nums');
/* 随机访问 */ /* 随机访问 */
@ -96,7 +96,7 @@ void main() {
remove(nums, 2); remove(nums, 2);
print("删除索引 2 处的元素,得到 nums = $nums"); print("删除索引 2 处的元素,得到 nums = $nums");
/* 遍历元素 */ /* 遍历数组 */
traverse(nums); traverse(nums);
/* 查找元素 */ /* 查找元素 */

View File

@ -43,12 +43,12 @@ void main() {
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
int count = 0; int count = 0;
for (var i = 0; i < nums.length; i++) { for (var i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
for (var n in nums) { for (var x in nums) {
count++; count += x;
} }
/* 拼接两个列表 */ /* 拼接两个列表 */

View File

@ -13,7 +13,7 @@ void backtrack(List<int> choices, int state, int n, List<int> res) {
// //
for (int choice in choices) { for (int choice in choices) {
// n // n
if (state + choice > n) break; if (state + choice > n) continue;
// //
backtrack(choices, state + choice, n, res); backtrack(choices, state + choice, n, res);
// 退 // 退

View File

@ -6,7 +6,7 @@ services:
args: args:
# 设置需要安装的语言,使用空格隔开 # 设置需要安装的语言,使用空格隔开
# Set the languages to be installed, separated by spaces # Set the languages to be installed, separated by spaces
LANGS: "python cpp csharp" LANGS: "python cpp java csharp"
image: hello-algo-code image: hello-algo-code
container_name: hello-algo-code container_name: hello-algo-code
stdin_open: true stdin_open: true

View File

@ -52,12 +52,17 @@ func traverse(nums []int) {
count := 0 count := 0
// 通过索引遍历数组 // 通过索引遍历数组
for i := 0; i < len(nums); i++ { for i := 0; i < len(nums); i++ {
count++ count += nums[i]
} }
count = 0 count = 0
// 直接遍历数组 // 直接遍历数组元素
for range nums { for _, num := range nums {
count++ count += num
}
// 同时遍历数据索引和元素
for i, num := range nums {
count += nums[i]
count += num
} }
} }

View File

@ -47,13 +47,12 @@ func TestList(t *testing.T) {
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
count := 0 count := 0
for i := 0; i < len(nums); i++ { for i := 0; i < len(nums); i++ {
count++ count += nums[i]
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0 count = 0
for range nums { for _, x := range nums {
count++ count += x
} }
/* 拼接两个列表 */ /* 拼接两个列表 */

View File

@ -14,7 +14,7 @@ func backtrack(choices []int, state, n int, res []int) {
for _, choice := range choices { for _, choice := range choices {
// 剪枝:不允许越过第 n 阶 // 剪枝:不允许越过第 n 阶
if state+choice > n { if state+choice > n {
break continue
} }
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
backtrack(choices, state+choice, n, res) backtrack(choices, state+choice, n, res)

View File

@ -54,11 +54,11 @@ public class array {
int count = 0; int count = 0;
// 通过索引遍历数组 // 通过索引遍历数组
for (int i = 0; i < nums.length; i++) { for (int i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
// 直接遍历数组 // 直接遍历数组元素
for (int num : nums) { for (int num : nums) {
count++; count += num;
} }
} }

View File

@ -17,8 +17,8 @@ public class list {
System.out.println("列表 nums = " + nums); System.out.println("列表 nums = " + nums);
/* 访问元素 */ /* 访问元素 */
int x = nums.get(1); int num = nums.get(1);
System.out.println("访问索引 1 处的元素,得到 x = " + x); System.out.println("访问索引 1 处的元素,得到 num = " + num);
/* 更新元素 */ /* 更新元素 */
nums.set(1, 0); nums.set(1, 0);
@ -47,13 +47,11 @@ public class list {
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
int count = 0; int count = 0;
for (int i = 0; i < nums.size(); i++) { for (int i = 0; i < nums.size(); i++) {
count++; count += nums.get(i);
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; for (int x : nums) {
for (int num : nums) { count += x;
count++;
} }
/* 拼接两个列表 */ /* 拼接两个列表 */

View File

@ -18,7 +18,7 @@ public class climbing_stairs_backtrack {
for (Integer choice : choices) { for (Integer choice : choices) {
// 剪枝不允许越过第 n // 剪枝不允许越过第 n
if (state + choice > n) if (state + choice > n)
break; continue;
// 尝试做出选择更新状态 // 尝试做出选择更新状态
backtrack(choices, state + choice, n, res); backtrack(choices, state + choice, n, res);
// 回退 // 回退

View File

@ -50,11 +50,11 @@ function traverse(nums) {
let count = 0; let count = 0;
// 通过索引遍历数组 // 通过索引遍历数组
for (let i = 0; i < nums.length; i++) { for (let i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
// 直接遍历数组 // 直接遍历数组元素
for (const num of nums) { for (const num of nums) {
count += 1; count += num;
} }
} }

View File

@ -39,13 +39,12 @@ console.log(`删除索引 3 处的元素,得到 nums = ${nums}`);
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
let count = 0; let count = 0;
for (let i = 0; i < nums.length; i++) { for (let i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
for (const n of nums) { for (const x of nums) {
count++; count += x;
} }
/* 拼接两个列表 */ /* 拼接两个列表 */

View File

@ -11,7 +11,7 @@ function backtrack(choices, state, n, res) {
// 遍历所有选择 // 遍历所有选择
for (const choice of choices) { for (const choice of choices) {
// 剪枝:不允许越过第 n 阶 // 剪枝:不允许越过第 n 阶
if (state + choice > n) break; if (state + choice > n) continue;
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
backtrack(choices, state + choice, n, res); backtrack(choices, state + choice, n, res);
// 回退 // 回退

View File

@ -50,13 +50,14 @@ def traverse(nums: list[int]):
count = 0 count = 0
# 通过索引遍历数组 # 通过索引遍历数组
for i in range(len(nums)): for i in range(len(nums)):
count += 1 count += nums[i]
# 直接遍历数组 # 直接遍历数组元素
for num in nums: for num in nums:
count += 1 count += num
# 同时遍历数据索引和元素 # 同时遍历数据索引和元素
for i, num in enumerate(nums): for i, num in enumerate(nums):
count += 1 count += nums[i]
count += num
def find(nums: list[int], target: int) -> int: def find(nums: list[int], target: int) -> int:

View File

@ -38,16 +38,13 @@ if __name__ == "__main__":
nums.pop(3) nums.pop(3)
print("\n删除索引 3 处的元素,得到 nums =", nums) print("\n删除索引 3 处的元素,得到 nums =", nums)
# 遍历列表 # 通过索引遍历列表
tmp = [] count = 0
for i in range(len(nums)): for i in range(len(nums)):
tmp.append(nums[i]) count += nums[i]
print(f"\n通过索引遍历列表得到 tmp = {tmp}") # 直接遍历列表元素
tmp.clear()
for num in nums: for num in nums:
tmp.append(num) count += num
print(f"\n直接遍历列表元素得到 tmp = {tmp}")
# 拼接两个列表 # 拼接两个列表
nums1 = [6, 8, 7, 10, 9] nums1 = [6, 8, 7, 10, 9]

View File

@ -14,7 +14,7 @@ def backtrack(choices: list[int], state: int, n: int, res: list[int]) -> int:
for choice in choices: for choice in choices:
# 剪枝:不允许越过第 n 阶 # 剪枝:不允许越过第 n 阶
if state + choice > n: if state + choice > n:
break continue
# 尝试:做出选择,更新状态 # 尝试:做出选择,更新状态
backtrack(choices, state + choice, n, res) backtrack(choices, state + choice, n, res)
# 回退 # 回退

View File

@ -35,7 +35,9 @@ def show_trunks(p: Trunk | None):
print(p.str, end="") print(p.str, end="")
def print_tree(root: TreeNode | None, prev: Trunk | None = None, is_right: bool = False): def print_tree(
root: TreeNode | None, prev: Trunk | None = None, is_right: bool = False
):
""" """
Print a binary tree Print a binary tree
This tree printer is borrowed from TECHIE DELIGHT This tree printer is borrowed from TECHIE DELIGHT

View File

@ -51,12 +51,12 @@ fn remove(nums: &mut Vec<i32>, index: usize) {
fn traverse(nums: &[i32]) { fn traverse(nums: &[i32]) {
let mut _count = 0; let mut _count = 0;
// 通过索引遍历数组 // 通过索引遍历数组
for _ in 0..nums.len() { for i in 0..nums.len() {
_count += 1; _count += nums[i];
} }
// 直接遍历数组 // 直接遍历数组元素
for _ in nums { for num in nums {
_count += 1; _count += num;
} }
} }

View File

@ -8,26 +8,26 @@ include!("../include/include.rs");
/* Driver Code */ /* Driver Code */
fn main() { fn main() {
// 初始化列表 // 初始化列表
let mut nums: Vec<i32> = vec![ 1, 3, 2, 5, 4 ]; let mut nums: Vec<i32> = vec![ 1, 3, 2, 5, 4 ];
print!("列表 nums = "); print!("列表 nums = ");
print_util::print_array(&nums); print_util::print_array(&nums);
// 访问元素 // 访问元素
let num = nums[1]; let num = nums[1];
println!("\n访问索引 1 处的元素,得到 num = {num}"); println!("\n访问索引 1 处的元素,得到 num = {num}");
// 更新元素 // 更新元素
nums[1] = 0; nums[1] = 0;
print!("将索引 1 处的元素更新为 0 ,得到 nums = "); print!("将索引 1 处的元素更新为 0 ,得到 nums = ");
print_util::print_array(&nums); print_util::print_array(&nums);
// 清空列表 // 清空列表
nums.clear(); nums.clear();
print!("\n清空列表后 nums = "); print!("\n清空列表后 nums = ");
print_util::print_array(&nums); print_util::print_array(&nums);
// 尾部添加元素 // 尾部添加元素
nums.push(1); nums.push(1);
nums.push(3); nums.push(3);
nums.push(2); nums.push(2);
@ -36,39 +36,35 @@ fn main() {
print!("\n添加元素后 nums = "); print!("\n添加元素后 nums = ");
print_util::print_array(&nums); print_util::print_array(&nums);
// 中间插入元素 // 中间插入元素
nums.insert(3, 6); nums.insert(3, 6);
print!("\n在索引 3 处插入数字 6 ,得到 nums = "); print!("\n在索引 3 处插入数字 6 ,得到 nums = ");
print_util::print_array(&nums); print_util::print_array(&nums);
// 删除元素 // 删除元素
nums.remove(3); nums.remove(3);
print!("\n删除索引 3 处的元素,得到 nums = "); print!("\n删除索引 3 处的元素,得到 nums = ");
print_util::print_array(&nums); print_util::print_array(&nums);
// 通过索引遍历列表 // 通过索引遍历列表
let mut _count = 0; let mut _count = 0;
for _ in 0..nums.len() { for i in 0..nums.len() {
_count += 1; _count += nums[i];
} }
// 直接遍历列表元素 // 直接遍历列表元素
_count = 0; _count = 0;
for _n in &nums { for x in &nums {
_count += 1; _count += x;
} }
// 或者
// nums.iter().for_each(|_| _count += 1);
// let _count = nums.iter().fold(0, |_count, _| _count + 1);
// 拼接两个列表 // 拼接两个列表
let mut nums1 = vec![ 6, 8, 7, 10, 9 ]; let mut nums1 = vec![ 6, 8, 7, 10, 9 ];
nums.append(&mut nums1); // append移动 之后 nums1 为空! nums.append(&mut nums1); // append移动 之后 nums1 为空!
// nums.extend(&nums1); // extend借用 nums1 能继续使用 // nums.extend(&nums1); // extend借用 nums1 能继续使用
print!("\n将列表 nums1 拼接到 nums 之后,得到 nums = "); print!("\n将列表 nums1 拼接到 nums 之后,得到 nums = ");
print_util::print_array(&nums); print_util::print_array(&nums);
// 排序列表 // 排序列表
nums.sort(); nums.sort();
print!("\n排序列表后 nums = "); print!("\n排序列表后 nums = ");
print_util::print_array(&nums); print_util::print_array(&nums);

View File

@ -11,7 +11,7 @@ fn backtrack(choices: &[i32], state: i32, n: i32, res: &mut [i32]) {
// 遍历所有选择 // 遍历所有选择
for &choice in choices { for &choice in choices {
// 剪枝:不允许越过第 n 阶 // 剪枝:不允许越过第 n 阶
if state + choice > n { break; } if state + choice > n { continue; }
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
backtrack(choices, state + choice, n, res); backtrack(choices, state + choice, n, res);
// 回退 // 回退

View File

@ -48,12 +48,12 @@ func remove(nums: inout [Int], index: Int) {
func traverse(nums: [Int]) { func traverse(nums: [Int]) {
var count = 0 var count = 0
// //
for _ in nums.indices { for i in nums.indices {
count += 1 count += nums[i]
} }
// //
for _ in nums { for num in nums {
count += 1 count += num
} }
} }

View File

@ -42,14 +42,13 @@ enum List {
/* */ /* */
var count = 0 var count = 0
for _ in nums.indices { for i in nums.indices {
count += 1 count += nums[i]
} }
/* */ /* */
count = 0 count = 0
for _ in nums { for x in nums {
count += 1 count += x
} }
/* */ /* */

View File

@ -14,7 +14,7 @@ func backtrack(choices: [Int], state: Int, n: Int, res: inout [Int]) {
for choice in choices { for choice in choices {
// n // n
if state + choice > n { if state + choice > n {
break continue
} }
backtrack(choices: choices, state: state + choice, n: n, res: &res) backtrack(choices: choices, state: state + choice, n: n, res: &res)
} }

View File

@ -50,11 +50,11 @@ function traverse(nums: number[]): void {
let count = 0; let count = 0;
// 通过索引遍历数组 // 通过索引遍历数组
for (let i = 0; i < nums.length; i++) { for (let i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
// 直接遍历数组 // 直接遍历数组元素
for (const num of nums) { for (const num of nums) {
count += 1; count += num;
} }
} }

View File

@ -39,13 +39,12 @@ console.log(`删除索引 3 处的元素,得到 nums = ${nums}`);
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
let count = 0; let count = 0;
for (let i = 0; i < nums.length; i++) { for (let i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
for (const n of nums) { for (const x of nums) {
count++; count += x;
} }
/* 拼接两个列表 */ /* 拼接两个列表 */

View File

@ -16,7 +16,7 @@ function backtrack(
// 遍历所有选择 // 遍历所有选择
for (const choice of choices) { for (const choice of choices) {
// 剪枝:不允许越过第 n 阶 // 剪枝:不允许越过第 n 阶
if (state + choice > n) break; if (state + choice > n) continue;
// 尝试:做出选择,更新状态 // 尝试:做出选择,更新状态
backtrack(choices, state + choice, n, res); backtrack(choices, state + choice, n, res);
// 回退 // 回退

View File

@ -51,12 +51,12 @@ pub fn traverse(nums: []i32) void {
// //
var i: i32 = 0; var i: i32 = 0;
while (i < nums.len) : (i += 1) { while (i < nums.len) : (i += 1) {
count += 1; count += nums[i];
} }
count = 0; count = 0;
// //
for (nums) |_| { for (nums) |num| {
count += 1; count += num;
} }
} }

View File

@ -52,13 +52,12 @@ pub fn main() !void {
var count: i32 = 0; var count: i32 = 0;
var i: i32 = 0; var i: i32 = 0;
while (i < nums.items.len) : (i += 1) { while (i < nums.items.len) : (i += 1) {
count += 1; count += nums[i];
} }
// //
count = 0; count = 0;
for (nums.items) |_| { for (nums.items) |x| {
count += 1; count += x;
} }
// //

View File

@ -14,7 +14,7 @@ fn backtrack(choices: []i32, state: i32, n: i32, res: std.ArrayList(i32)) void {
for (choices) |choice| { for (choices) |choice| {
// n // n
if (state + choice > n) { if (state + choice > n) {
break; continue;
} }
// //
backtrack(choices, state + choice, n, res); backtrack(choices, state + choice, n, res);

View File

@ -2,6 +2,6 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![附录](../assets/covers/chapter_appendix.jpg){ width="600" } ![附录](../assets/covers/chapter_appendix.jpg)
</div> </div>

View File

@ -17,13 +17,13 @@
| 递归树 | recursion tree | | 递归树 | recursion tree |
| 大 $O$ 记号 | big-$O$ notation | | 大 $O$ 记号 | big-$O$ notation |
| 渐近上界 | asymptotic upper bound | | 渐近上界 | asymptotic upper bound |
| 原码 | true form | | 原码 | signmagnitude |
| 反码 | 1's complement code | | 反码 | 1's complement |
| 补码 | 2's complement code | | 补码 | 2's complement |
| 数组 | array | | 数组 | array |
| 索引 | index | | 索引 | index |
| 链表 | linked list | | 链表 | linked list |
| 链表节点 | linked list node, list node | | 链表节点 | linked list node, list node |
| 列表 | list | | 列表 | list |
| 动态数组 | dynamic array | | 动态数组 | dynamic array |
| 栈 | stack | | 栈 | stack |
@ -56,8 +56,8 @@
| 完全二叉树 | complete binary tree | | 完全二叉树 | complete binary tree |
| 完满二叉树 | full binary tree | | 完满二叉树 | full binary tree |
| 平衡二叉树 | balanced binary tree | | 平衡二叉树 | balanced binary tree |
| AVL 树 | AVL tree | | AVL 树 | AVL tree |
| 红黑树 | red-black tree | | 红黑树 | red-black tree |
| 层序遍历 | level-order traversal | | 层序遍历 | level-order traversal |
| 广度优先遍历 | breadth-first traversal | | 广度优先遍历 | breadth-first traversal |
| 深度优先遍历 | depth-first traversal | | 深度优先遍历 | depth-first traversal |

Binary file not shown.

Before

Width:  |  Height:  |  Size: 20 KiB

After

Width:  |  Height:  |  Size: 21 KiB

View File

@ -1,10 +1,6 @@
# 数组与链表 # 数组与链表
<div class="center-table" markdown> ![数组与链表](../assets/covers/chapter_array_and_linkedlist.jpg)
![数组与链表](../assets/covers/chapter_array_and_linkedlist.jpg){ width="600" }
</div>
!!! abstract !!! abstract

View File

@ -494,12 +494,11 @@
# 通过索引遍历列表 # 通过索引遍历列表
count = 0 count = 0
for i in range(len(nums)): for i in range(len(nums)):
count += 1 count += nums[i]
# 直接遍历列表元素 # 直接遍历列表元素
count = 0
for num in nums: for num in nums:
count += 1 count += num
``` ```
=== "C++" === "C++"
@ -508,13 +507,13 @@
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
int count = 0; int count = 0;
for (int i = 0; i < nums.size(); i++) { for (int i = 0; i < nums.size(); i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
for (int num : nums) { for (int num : nums) {
count++; count += num;
} }
``` ```
@ -524,13 +523,12 @@
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
int count = 0; int count = 0;
for (int i = 0; i < nums.size(); i++) { for (int i = 0; i < nums.size(); i++) {
count++; count += nums.get(i);
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0;
for (int num : nums) { for (int num : nums) {
count++; count += num;
} }
``` ```
@ -540,13 +538,13 @@
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
int count = 0; int count = 0;
for (int i = 0; i < nums.Count; i++) { for (int i = 0; i < nums.Count; i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
foreach (int num in nums) { foreach (int num in nums) {
count++; count += num;
} }
``` ```
@ -556,13 +554,13 @@
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
count := 0 count := 0
for i := 0; i < len(nums); i++ { for i := 0; i < len(nums); i++ {
count++ count += nums[i]
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0 count = 0
for range nums { for _, num := range nums {
count++ count += num
} }
``` ```
@ -571,14 +569,14 @@
```swift title="list.swift" ```swift title="list.swift"
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
var count = 0 var count = 0
for _ in nums.indices { for i in nums.indices {
count += 1 count += nums[i]
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0 count = 0
for _ in nums { for num in nums {
count += 1 count += num
} }
``` ```
@ -588,13 +586,13 @@
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
let count = 0; let count = 0;
for (let i = 0; i < nums.length; i++) { for (let i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
for (const num of nums) { for (const num of nums) {
count++; count += num;
} }
``` ```
@ -604,13 +602,13 @@
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
let count = 0; let count = 0;
for (let i = 0; i < nums.length; i++) { for (let i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
for (const num of nums) { for (const num of nums) {
count++; count += num;
} }
``` ```
@ -619,30 +617,30 @@
```dart title="list.dart" ```dart title="list.dart"
/* 通过索引遍历列表 */ /* 通过索引遍历列表 */
int count = 0; int count = 0;
for (int i = 0; i < nums.length; i++) { for (var i = 0; i < nums.length; i++) {
count++; count += nums[i];
} }
/* 直接遍历列表元素 */ /* 直接遍历列表元素 */
count = 0; count = 0;
for (int num in nums) { for (var num in nums) {
count++; count += num;
} }
``` ```
=== "Rust" === "Rust"
```rust title="list.rs" ```rust title="list.rs"
/* 通过索引遍历列表 */ // 通过索引遍历列表
let mut count = 0; let mut _count = 0;
for (index, value) in nums.iter().enumerate() { for i in 0..nums.len() {
count += 1; _count += nums[i];
} }
/* 直接遍历列表元素 */ // 直接遍历列表元素
let mut count = 0; _count = 0;
for value in nums.iter() { for num in &nums {
count += 1; _count += num;
} }
``` ```
@ -659,13 +657,13 @@
var count: i32 = 0; var count: i32 = 0;
var i: i32 = 0; var i: i32 = 0;
while (i < nums.items.len) : (i += 1) { while (i < nums.items.len) : (i += 1) {
count += 1; count += nums[i];
} }
// 直接遍历列表元素 // 直接遍历列表元素
count = 0; count = 0;
for (nums.items) |_| { for (nums.items) |num| {
count += 1; count += num;
} }
``` ```

View File

@ -33,7 +33,7 @@
不修改 `P.next` 也可以。从该链表的角度看,从头节点遍历到尾节点已经遇不到 `P` 了。这意味着节点 `P` 已经从链表中删除了,此时节点 `P` 指向哪里都不会对这条链表产生影响了。 不修改 `P.next` 也可以。从该链表的角度看,从头节点遍历到尾节点已经遇不到 `P` 了。这意味着节点 `P` 已经从链表中删除了,此时节点 `P` 指向哪里都不会对这条链表产生影响了。
从垃圾回收的角度看,对于 Java、Python、Go 等拥有自动垃圾回收的语言来说,节点 `P` 是否被回收取决于是否仍存在指向它的引用,而不是 `P.next` 的值。在 C 和 C++ 等语言中,我们需要手动释放节点内存。 从垃圾回收的角度看,对于 Java、Python、Go 等拥有自动垃圾回收的语言来说,节点 `P` 是否被回收取决于是否仍存在指向它的引用,而不是 `P.next` 的值。在 C 和 C++ 等语言中,我们需要手动释放节点内存。
!!! question "在链表中插入和删除操作的时间复杂度是 $O(1)$ 。但是增删之前都需要 $O(n)$ 查找元素,那为什么时间复杂度不是 $O(n)$ 呢?" !!! question "在链表中插入和删除操作的时间复杂度是 $O(1)$ 。但是增删之前都需要 $O(n)$ 查找元素,那为什么时间复杂度不是 $O(n)$ 呢?"

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![回溯](../assets/covers/chapter_backtracking.jpg){ width="600" } ![回溯](../assets/covers/chapter_backtracking.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![复杂度分析](../assets/covers/chapter_complexity_analysis.jpg){ width="600" } ![复杂度分析](../assets/covers/chapter_complexity_analysis.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![数据结构](../assets/covers/chapter_data_structure.jpg){ width="600" } ![数据结构](../assets/covers/chapter_data_structure.jpg)
</div> </div>

View File

@ -18,7 +18,7 @@
![原码、反码与补码之间的相互转换](number_encoding.assets/1s_2s_complement.png) ![原码、反码与补码之间的相互转换](number_encoding.assets/1s_2s_complement.png)
「原码 true form」虽然最直观,但存在一些局限性。一方面,**负数的原码不能直接用于运算**。例如在原码下计算 $1 + (-2)$ ,得到的结果是 $-3$ ,这显然是不对的。 「原码 signmagnitude」虽然最直观但存在一些局限性。一方面**负数的原码不能直接用于运算**。例如在原码下计算 $1 + (-2)$ ,得到的结果是 $-3$ ,这显然是不对的。
$$ $$
\begin{aligned} \begin{aligned}
@ -29,7 +29,7 @@ $$
\end{aligned} \end{aligned}
$$ $$
为了解决此问题,计算机引入了「反码 1's complement code」。如果我们先将原码转换为反码,并在反码下计算 $1 + (-2)$ ,最后将结果从反码转化回原码,则可得到正确结果 $-1$ 。 为了解决此问题,计算机引入了「反码 1's complement」。如果我们先将原码转换为反码并在反码下计算 $1 + (-2)$ ,最后将结果从反码转化回原码,则可得到正确结果 $-1$ 。
$$ $$
\begin{aligned} \begin{aligned}
@ -51,7 +51,7 @@ $$
\end{aligned} \end{aligned}
$$ $$
与原码一样,反码也存在正负零歧义问题,因此计算机进一步引入了「补码 2's complement code」。我们先来观察一下负零的原码、反码、补码的转换过程: 与原码一样,反码也存在正负零歧义问题,因此计算机进一步引入了「补码 2's complement」。我们先来观察一下负零的原码、反码、补码的转换过程
$$ $$
\begin{aligned} \begin{aligned}

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![分治](../assets/covers/chapter_divide_and_conquer.jpg){ width="600" } ![分治](../assets/covers/chapter_divide_and_conquer.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![动态规划](../assets/covers/chapter_dynamic_programming.jpg){ width="600" } ![动态规划](../assets/covers/chapter_dynamic_programming.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![](../assets/covers/chapter_graph.jpg){ width="600" } ![](../assets/covers/chapter_graph.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![贪心](../assets/covers/chapter_greedy.jpg){ width="600" } ![贪心](../assets/covers/chapter_greedy.jpg)
</div> </div>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 18 KiB

After

Width:  |  Height:  |  Size: 18 KiB

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![哈希表](../assets/covers/chapter_hashing.jpg){ width="600" } ![哈希表](../assets/covers/chapter_hashing.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![](../assets/covers/chapter_heap.jpg){ width="600" } ![](../assets/covers/chapter_heap.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![初识算法](../assets/covers/chapter_introduction.jpg){ width="600" } ![初识算法](../assets/covers/chapter_introduction.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![前言](../assets/covers/chapter_preface.jpg){ width="600" } ![前言](../assets/covers/chapter_preface.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![搜索](../assets/covers/chapter_searching.jpg){ width="600" } ![搜索](../assets/covers/chapter_searching.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![排序](../assets/covers/chapter_sorting.jpg){ width="600" } ![排序](../assets/covers/chapter_sorting.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![栈与队列](../assets/covers/chapter_stack_and_queue.jpg){ width="600" } ![栈与队列](../assets/covers/chapter_stack_and_queue.jpg)
</div> </div>

View File

@ -2,7 +2,7 @@
<div class="center-table" markdown> <div class="center-table" markdown>
![](../assets/covers/chapter_tree.jpg){ width="600" } ![](../assets/covers/chapter_tree.jpg)
</div> </div>

View File

@ -8,8 +8,8 @@ hide:
<h1 align="center"> </h1> <h1 align="center"> </h1>
<p align="center"> <p align="center">
<img src="index.assets/conceptual_rendering.png" width="250"> <img src="index.assets/conceptual_rendering.png" width="200">
<img src="index.assets/hello_algo_mindmap_tp.png" width="400"> <img src="index.assets/hello_algo_mindmap_tp.png" width="320">
</p> </p>
<h2 align="center"> 《 Hello 算法 》</h2> <h2 align="center"> 《 Hello 算法 》</h2>

View File

@ -25,7 +25,7 @@
--md-default-fg-color: #adbac7; --md-default-fg-color: #adbac7;
--md-default-bg-color: #22272e; --md-default-bg-color: #22272e;
--md-code-bg-color: #1D2126; --md-code-bg-color: #1d2126;
--md-code-fg-color: #adbac7; --md-code-fg-color: #adbac7;
--md-accent-fg-color: #aaa; --md-accent-fg-color: #aaa;
@ -43,6 +43,23 @@
color: var(--md-default-fg-color) !important; color: var(--md-default-fg-color) !important;
} }
/* Figure class */
.animation-figure {
border-radius: 0.63rem;
display: block;
margin: 0 auto;
}
/* Cover image class */
.cover-image {
width: 28rem;
height: auto;
border-radius: 0.3rem;
box-shadow: var(--md-shadow-z2);
display: block;
margin: 0 auto;
}
/* Center Markdown Tables (requires md_in_html extension) */ /* Center Markdown Tables (requires md_in_html extension) */
.center-table { .center-table {
text-align: center; text-align: center;
@ -82,12 +99,6 @@
text-transform: none; text-transform: none;
} }
/* Image align center */
.center {
display: block;
margin: 0 auto;
}
/* font-family setting for Win10 */ /* font-family setting for Win10 */
body { body {
--md-text-font-family: -apple-system, BlinkMacSystemFont, --md-text-font-family: -apple-system, BlinkMacSystemFont,