From baac2d11a7ddb7c4dd48da8361cb320a9a357c50 Mon Sep 17 00:00:00 2001 From: krahets Date: Sun, 8 Oct 2023 01:43:28 +0800 Subject: [PATCH] build --- zh/chapter_array_and_linkedlist/array.md | 12 +- .../linked_list.md | 18 +-- zh/chapter_array_and_linkedlist/list.md | 28 ++-- .../backtracking_algorithm.md | 56 +++---- zh/chapter_backtracking/n_queens_problem.md | 16 +- .../permutations_problem.md | 20 +-- zh/chapter_backtracking/subset_sum_problem.md | 36 ++--- .../iteration_and_recursion.md | 46 ++++-- .../space_complexity.md | 49 +++--- .../time_complexity.md | 48 +++--- .../binary_search_recur.md | 37 ++++- .../build_binary_tree_problem.md | 14 +- .../hanota_problem.md | 49 ++++-- .../dp_problem_features.md | 53 ++++++- .../dp_solution_pipeline.md | 98 ++++++++++-- .../edit_distance_problem.md | 4 +- .../intro_to_dynamic_programming.md | 32 ++-- .../knapsack_problem.md | 99 ++++++++++-- .../unbounded_knapsack_problem.md | 150 ++++++++++++++++-- zh/chapter_graph/graph_operations.md | 50 +++--- zh/chapter_graph/graph_traversal.md | 20 +-- .../fractional_knapsack_problem.md | 2 +- zh/chapter_greedy/greedy_algorithm.md | 2 +- zh/chapter_greedy/max_capacity_problem.md | 2 +- .../max_product_cutting_problem.md | 2 +- zh/chapter_hashing/hash_algorithm.md | 10 +- zh/chapter_hashing/hash_collision.md | 68 ++++---- zh/chapter_hashing/hash_map.md | 48 +++--- zh/chapter_heap/build_heap.md | 4 +- zh/chapter_heap/heap.md | 42 ++--- zh/chapter_heap/top_k.md | 4 +- zh/chapter_searching/binary_search.md | 4 +- zh/chapter_searching/binary_search_edge.md | 8 +- .../binary_search_insertion.md | 4 +- .../replace_linear_by_hashing.md | 4 +- zh/chapter_sorting/bubble_sort.md | 12 +- zh/chapter_sorting/bucket_sort.md | 4 +- zh/chapter_sorting/counting_sort.md | 4 +- zh/chapter_sorting/heap_sort.md | 8 +- zh/chapter_sorting/insertion_sort.md | 2 +- zh/chapter_sorting/merge_sort.md | 10 +- zh/chapter_sorting/quick_sort.md | 40 +++-- zh/chapter_sorting/radix_sort.md | 12 +- zh/chapter_sorting/selection_sort.md | 2 +- zh/chapter_stack_and_queue/deque.md | 112 ++++++------- zh/chapter_stack_and_queue/queue.md | 50 +++--- zh/chapter_stack_and_queue/stack.md | 55 +++---- .../array_representation_of_tree.md | 56 +++---- zh/chapter_tree/avl_tree.md | 74 ++++----- zh/chapter_tree/binary_search_tree.md | 12 +- zh/chapter_tree/binary_tree.md | 12 +- zh/chapter_tree/binary_tree_traversal.md | 20 +-- 52 files changed, 999 insertions(+), 625 deletions(-) diff --git a/zh/chapter_array_and_linkedlist/array.md b/zh/chapter_array_and_linkedlist/array.md index c7e95397f..e6045cd1b 100755 --- a/zh/chapter_array_and_linkedlist/array.md +++ b/zh/chapter_array_and_linkedlist/array.md @@ -173,7 +173,7 @@ comments: true ```csharp title="array.cs" /* 随机访问元素 */ - int randomAccess(int[] nums) { + int RandomAccess(int[] nums) { Random random = new(); // 在区间 [0, nums.Length) 中随机抽取一个数字 int randomIndex = random.Next(nums.Length); @@ -341,7 +341,7 @@ comments: true ```csharp title="array.cs" /* 在数组的索引 index 处插入元素 num */ - void insert(int[] nums, int num, int index) { + void Insert(int[] nums, int num, int index) { // 把索引 index 以及之后的所有元素向后移动一位 for (int i = nums.Length - 1; i > index; i--) { nums[i] = nums[i - 1]; @@ -512,7 +512,7 @@ comments: true ```csharp title="array.cs" /* 删除索引 index 处元素 */ - void remove(int[] nums, int index) { + void Remove(int[] nums, int index) { // 把索引 index 之后的所有元素向前移动一位 for (int i = index; i < nums.Length - 1; i++) { nums[i] = nums[i + 1]; @@ -680,7 +680,7 @@ comments: true ```csharp title="array.cs" /* 遍历数组 */ - void traverse(int[] nums) { + void Traverse(int[] nums) { int count = 0; // 通过索引遍历数组 for (int i = 0; i < nums.Length; i++) { @@ -879,7 +879,7 @@ comments: true ```csharp title="array.cs" /* 在数组中查找指定元素 */ - int find(int[] nums, int target) { + int Find(int[] nums, int target) { for (int i = 0; i < nums.Length; i++) { if (nums[i] == target) return i; @@ -1053,7 +1053,7 @@ comments: true ```csharp title="array.cs" /* 扩展数组长度 */ - int[] extend(int[] nums, int enlarge) { + int[] Extend(int[] nums, int enlarge) { // 初始化一个扩展长度后的数组 int[] res = new int[nums.Length + enlarge]; // 将原数组中的所有元素复制到新数组 diff --git a/zh/chapter_array_and_linkedlist/linked_list.md b/zh/chapter_array_and_linkedlist/linked_list.md index d2314aa01..44dd1c036 100755 --- a/zh/chapter_array_and_linkedlist/linked_list.md +++ b/zh/chapter_array_and_linkedlist/linked_list.md @@ -252,11 +252,11 @@ comments: true ```csharp title="linked_list.cs" /* 初始化链表 1 -> 3 -> 2 -> 5 -> 4 */ // 初始化各个节点 - ListNode n0 = new ListNode(1); - ListNode n1 = new ListNode(3); - ListNode n2 = new ListNode(2); - ListNode n3 = new ListNode(5); - ListNode n4 = new ListNode(4); + ListNode n0 = new(1); + ListNode n1 = new(3); + ListNode n2 = new(2); + ListNode n3 = new(5); + ListNode n4 = new(4); // 构建引用指向 n0.next = n1; n1.next = n2; @@ -449,7 +449,7 @@ comments: true ```csharp title="linked_list.cs" /* 在链表的节点 n0 之后插入节点 P */ - void insert(ListNode n0, ListNode P) { + void Insert(ListNode n0, ListNode P) { ListNode? n1 = n0.next; P.next = n1; n0.next = P; @@ -602,7 +602,7 @@ comments: true ```csharp title="linked_list.cs" /* 删除链表的节点 n0 之后的首个节点 */ - void remove(ListNode n0) { + void Remove(ListNode n0) { if (n0.next == null) return; // n0 -> P -> n1 @@ -778,7 +778,7 @@ comments: true ```csharp title="linked_list.cs" /* 访问链表中索引为 index 的节点 */ - ListNode? access(ListNode head, int index) { + ListNode? Access(ListNode head, int index) { for (int i = 0; i < index; i++) { if (head == null) return null; @@ -957,7 +957,7 @@ comments: true ```csharp title="linked_list.cs" /* 在链表中查找值为 target 的首个节点 */ - int find(ListNode head, int target) { + int Find(ListNode head, int target) { int index = 0; while (head != null) { if (head.val == target) diff --git a/zh/chapter_array_and_linkedlist/list.md b/zh/chapter_array_and_linkedlist/list.md index f21a968a3..2f1ab11c6 100755 --- a/zh/chapter_array_and_linkedlist/list.md +++ b/zh/chapter_array_and_linkedlist/list.md @@ -51,7 +51,7 @@ comments: true ```csharp title="list.cs" /* 初始化列表 */ // 无初始值 - List list1 = new (); + List list1 = new(); // 有初始值 int[] numbers = new int[] { 1, 3, 2, 5, 4 }; List list = numbers.ToList(); @@ -1170,7 +1170,7 @@ comments: true private int[] nums; // 数组(存储列表元素) private int numsCapacity = 10; // 列表容量 private int numsSize = 0; // 列表长度(即当前元素数量) - private int extendRatio = 2; // 每次列表扩容的倍数 + private readonly int extendRatio = 2; // 每次列表扩容的倍数 /* 构造方法 */ public MyList() { @@ -1178,17 +1178,17 @@ comments: true } /* 获取列表长度(即当前元素数量)*/ - public int size() { + public int Size() { return numsSize; } /* 获取列表容量 */ - public int capacity() { + public int Capacity() { return numsCapacity; } /* 访问元素 */ - public int get(int index) { + public int Get(int index) { // 索引如果越界则抛出异常,下同 if (index < 0 || index >= numsSize) throw new IndexOutOfRangeException("索引越界"); @@ -1196,29 +1196,29 @@ comments: true } /* 更新元素 */ - public void set(int index, int num) { + public void Set(int index, int num) { if (index < 0 || index >= numsSize) throw new IndexOutOfRangeException("索引越界"); nums[index] = num; } /* 尾部添加元素 */ - public void add(int num) { + public void Add(int num) { // 元素数量超出容量时,触发扩容机制 if (numsSize == numsCapacity) - extendCapacity(); + ExtendCapacity(); nums[numsSize] = num; // 更新元素数量 numsSize++; } /* 中间插入元素 */ - public void insert(int index, int num) { + public void Insert(int index, int num) { if (index < 0 || index >= numsSize) throw new IndexOutOfRangeException("索引越界"); // 元素数量超出容量时,触发扩容机制 if (numsSize == numsCapacity) - extendCapacity(); + ExtendCapacity(); // 将索引 index 以及之后的元素都向后移动一位 for (int j = numsSize - 1; j >= index; j--) { nums[j + 1] = nums[j]; @@ -1229,7 +1229,7 @@ comments: true } /* 删除元素 */ - public int remove(int index) { + public int Remove(int index) { if (index < 0 || index >= numsSize) throw new IndexOutOfRangeException("索引越界"); int num = nums[index]; @@ -1244,7 +1244,7 @@ comments: true } /* 列表扩容 */ - public void extendCapacity() { + public void ExtendCapacity() { // 新建一个长度为 numsCapacity * extendRatio 的数组,并将原数组拷贝到新数组 Array.Resize(ref nums, numsCapacity * extendRatio); // 更新列表容量 @@ -1252,11 +1252,11 @@ comments: true } /* 将列表转换为数组 */ - public int[] toArray() { + public int[] ToArray() { // 仅转换有效长度范围内的列表元素 int[] nums = new int[numsSize]; for (int i = 0; i < numsSize; i++) { - nums[i] = get(i); + nums[i] = Get(i); } return nums; } diff --git a/zh/chapter_backtracking/backtracking_algorithm.md b/zh/chapter_backtracking/backtracking_algorithm.md index b7e0fa514..83a1bab9f 100644 --- a/zh/chapter_backtracking/backtracking_algorithm.md +++ b/zh/chapter_backtracking/backtracking_algorithm.md @@ -66,7 +66,7 @@ comments: true ```csharp title="preorder_traversal_i_compact.cs" /* 前序遍历:例题一 */ - void preOrder(TreeNode root) { + void PreOrder(TreeNode root) { if (root == null) { return; } @@ -74,8 +74,8 @@ comments: true // 记录解 res.Add(root); } - preOrder(root.left); - preOrder(root.right); + PreOrder(root.left); + PreOrder(root.right); } ``` @@ -277,7 +277,7 @@ comments: true ```csharp title="preorder_traversal_ii_compact.cs" /* 前序遍历:例题二 */ - void preOrder(TreeNode root) { + void PreOrder(TreeNode root) { if (root == null) { return; } @@ -287,8 +287,8 @@ comments: true // 记录解 res.Add(new List(path)); } - preOrder(root.left); - preOrder(root.right); + PreOrder(root.left); + PreOrder(root.right); // 回退 path.RemoveAt(path.Count - 1); } @@ -580,7 +580,7 @@ comments: true ```csharp title="preorder_traversal_iii_compact.cs" /* 前序遍历:例题三 */ - void preOrder(TreeNode root) { + void PreOrder(TreeNode root) { // 剪枝 if (root == null || root.val == 3) { return; @@ -591,8 +591,8 @@ comments: true // 记录解 res.Add(new List(path)); } - preOrder(root.left); - preOrder(root.right); + PreOrder(root.left); + PreOrder(root.right); // 回退 path.RemoveAt(path.Count - 1); } @@ -865,23 +865,23 @@ comments: true ```csharp title="" /* 回溯算法框架 */ - void backtrack(State state, List choices, List res) { + void Backtrack(State state, List choices, List res) { // 判断是否为解 - if (isSolution(state)) { + if (IsSolution(state)) { // 记录解 - recordSolution(state, res); + RecordSolution(state, res); // 停止继续搜索 return; } // 遍历所有选择 foreach (Choice choice in choices) { // 剪枝:判断选择是否合法 - if (isValid(state, choice)) { + if (IsValid(state, choice)) { // 尝试:做出选择,更新状态 - makeChoice(state, choice); - backtrack(state, choices, res); + MakeChoice(state, choice); + Backtrack(state, choices, res); // 回退:撤销选择,恢复到之前的状态 - undoChoice(state, choice); + UndoChoice(state, choice); } } } @@ -1225,47 +1225,47 @@ comments: true ```csharp title="preorder_traversal_iii_template.cs" /* 判断当前状态是否为解 */ - bool isSolution(List state) { + bool IsSolution(List state) { return state.Count != 0 && state[^1].val == 7; } /* 记录解 */ - void recordSolution(List state, List> res) { + void RecordSolution(List state, List> res) { res.Add(new List(state)); } /* 判断在当前状态下,该选择是否合法 */ - bool isValid(List state, TreeNode choice) { + bool IsValid(List state, TreeNode choice) { return choice != null && choice.val != 3; } /* 更新状态 */ - void makeChoice(List state, TreeNode choice) { + void MakeChoice(List state, TreeNode choice) { state.Add(choice); } /* 恢复状态 */ - void undoChoice(List state, TreeNode choice) { + void UndoChoice(List state, TreeNode choice) { state.RemoveAt(state.Count - 1); } /* 回溯算法:例题三 */ - void backtrack(List state, List choices, List> res) { + void Backtrack(List state, List choices, List> res) { // 检查是否为解 - if (isSolution(state)) { + if (IsSolution(state)) { // 记录解 - recordSolution(state, res); + RecordSolution(state, res); } // 遍历所有选择 foreach (TreeNode choice in choices) { // 剪枝:检查选择是否合法 - if (isValid(state, choice)) { + if (IsValid(state, choice)) { // 尝试:做出选择,更新状态 - makeChoice(state, choice); + MakeChoice(state, choice); // 进行下一轮选择 - backtrack(state, new List { choice.left, choice.right }, res); + Backtrack(state, new List { choice.left, choice.right }, res); // 回退:撤销选择,恢复到之前的状态 - undoChoice(state, choice); + UndoChoice(state, choice); } } } diff --git a/zh/chapter_backtracking/n_queens_problem.md b/zh/chapter_backtracking/n_queens_problem.md index 84897e192..3114ba4e6 100644 --- a/zh/chapter_backtracking/n_queens_problem.md +++ b/zh/chapter_backtracking/n_queens_problem.md @@ -203,11 +203,11 @@ comments: true ```csharp title="n_queens.cs" /* 回溯算法:N 皇后 */ - void backtrack(int row, int n, List> state, List>> res, + void Backtrack(int row, int n, List> state, List>> res, bool[] cols, bool[] diags1, bool[] diags2) { // 当放置完所有行时,记录解 if (row == n) { - List> copyState = new List>(); + List> copyState = new(); foreach (List sRow in state) { copyState.Add(new List(sRow)); } @@ -225,7 +225,7 @@ comments: true state[row][col] = "Q"; cols[col] = diags1[diag1] = diags2[diag2] = true; // 放置下一行 - backtrack(row + 1, n, state, res, cols, diags1, diags2); + Backtrack(row + 1, n, state, res, cols, diags1, diags2); // 回退:将该格子恢复为空位 state[row][col] = "#"; cols[col] = diags1[diag1] = diags2[diag2] = false; @@ -234,11 +234,11 @@ comments: true } /* 求解 N 皇后 */ - List>> nQueens(int n) { + List>> NQueens(int n) { // 初始化 n*n 大小的棋盘,其中 'Q' 代表皇后,'#' 代表空位 - List> state = new List>(); + List> state = new(); for (int i = 0; i < n; i++) { - List row = new List(); + List row = new(); for (int j = 0; j < n; j++) { row.Add("#"); } @@ -247,9 +247,9 @@ comments: true bool[] cols = new bool[n]; // 记录列是否有皇后 bool[] diags1 = new bool[2 * n - 1]; // 记录主对角线是否有皇后 bool[] diags2 = new bool[2 * n - 1]; // 记录副对角线是否有皇后 - List>> res = new List>>(); + List>> res = new(); - backtrack(0, n, state, res, cols, diags1, diags2); + Backtrack(0, n, state, res, cols, diags1, diags2); return res; } diff --git a/zh/chapter_backtracking/permutations_problem.md b/zh/chapter_backtracking/permutations_problem.md index ce5898ee3..877219954 100644 --- a/zh/chapter_backtracking/permutations_problem.md +++ b/zh/chapter_backtracking/permutations_problem.md @@ -162,7 +162,7 @@ comments: true ```csharp title="permutations_i.cs" /* 回溯算法:全排列 I */ - void backtrack(List state, int[] choices, bool[] selected, List> res) { + void Backtrack(List state, int[] choices, bool[] selected, List> res) { // 当状态长度等于元素数量时,记录解 if (state.Count == choices.Length) { res.Add(new List(state)); @@ -177,7 +177,7 @@ comments: true selected[i] = true; state.Add(choice); // 进行下一轮选择 - backtrack(state, choices, selected, res); + Backtrack(state, choices, selected, res); // 回退:撤销选择,恢复到之前的状态 selected[i] = false; state.RemoveAt(state.Count - 1); @@ -186,9 +186,9 @@ comments: true } /* 全排列 I */ - List> permutationsI(int[] nums) { - List> res = new List>(); - backtrack(new List(), nums, new bool[nums.Length], res); + List> PermutationsI(int[] nums) { + List> res = new(); + Backtrack(new List(), nums, new bool[nums.Length], res); return res; } ``` @@ -618,7 +618,7 @@ comments: true ```csharp title="permutations_ii.cs" /* 回溯算法:全排列 II */ - void backtrack(List state, int[] choices, bool[] selected, List> res) { + void Backtrack(List state, int[] choices, bool[] selected, List> res) { // 当状态长度等于元素数量时,记录解 if (state.Count == choices.Length) { res.Add(new List(state)); @@ -635,7 +635,7 @@ comments: true selected[i] = true; state.Add(choice); // 进行下一轮选择 - backtrack(state, choices, selected, res); + Backtrack(state, choices, selected, res); // 回退:撤销选择,恢复到之前的状态 selected[i] = false; state.RemoveAt(state.Count - 1); @@ -644,9 +644,9 @@ comments: true } /* 全排列 II */ - List> permutationsII(int[] nums) { - List> res = new List>(); - backtrack(new List(), nums, new bool[nums.Length], res); + List> PermutationsII(int[] nums) { + List> res = new(); + Backtrack(new List(), nums, new bool[nums.Length], res); return res; } ``` diff --git a/zh/chapter_backtracking/subset_sum_problem.md b/zh/chapter_backtracking/subset_sum_problem.md index b00d00da9..1de720aea 100644 --- a/zh/chapter_backtracking/subset_sum_problem.md +++ b/zh/chapter_backtracking/subset_sum_problem.md @@ -131,7 +131,7 @@ comments: true ```csharp title="subset_sum_i_naive.cs" /* 回溯算法:子集和 I */ - void backtrack(List state, int target, int total, int[] choices, List> res) { + void Backtrack(List state, int target, int total, int[] choices, List> res) { // 子集和等于 target 时,记录解 if (total == target) { res.Add(new List(state)); @@ -146,18 +146,18 @@ comments: true // 尝试:做出选择,更新元素和 total state.Add(choices[i]); // 进行下一轮选择 - backtrack(state, target, total + choices[i], choices, res); + Backtrack(state, target, total + choices[i], choices, res); // 回退:撤销选择,恢复到之前的状态 state.RemoveAt(state.Count - 1); } } /* 求解子集和 I(包含重复子集) */ - List> subsetSumINaive(int[] nums, int target) { - List state = new List(); // 状态(子集) + List> SubsetSumINaive(int[] nums, int target) { + List state = new(); // 状态(子集) int total = 0; // 子集和 - List> res = new List>(); // 结果列表(子集列表) - backtrack(state, target, total, nums, res); + List> res = new(); // 结果列表(子集列表) + Backtrack(state, target, total, nums, res); return res; } ``` @@ -588,7 +588,7 @@ comments: true ```csharp title="subset_sum_i.cs" /* 回溯算法:子集和 I */ - void backtrack(List state, int target, int[] choices, int start, List> res) { + void Backtrack(List state, int target, int[] choices, int start, List> res) { // 子集和等于 target 时,记录解 if (target == 0) { res.Add(new List(state)); @@ -605,19 +605,19 @@ comments: true // 尝试:做出选择,更新 target, start state.Add(choices[i]); // 进行下一轮选择 - backtrack(state, target - choices[i], choices, i, res); + Backtrack(state, target - choices[i], choices, i, res); // 回退:撤销选择,恢复到之前的状态 state.RemoveAt(state.Count - 1); } } /* 求解子集和 I */ - List> subsetSumI(int[] nums, int target) { - List state = new List(); // 状态(子集) + List> SubsetSumI(int[] nums, int target) { + List state = new(); // 状态(子集) Array.Sort(nums); // 对 nums 进行排序 int start = 0; // 遍历起始点 - List> res = new List>(); // 结果列表(子集列表) - backtrack(state, target, nums, start, res); + List> res = new(); // 结果列表(子集列表) + Backtrack(state, target, nums, start, res); return res; } ``` @@ -1069,7 +1069,7 @@ comments: true ```csharp title="subset_sum_ii.cs" /* 回溯算法:子集和 II */ - void backtrack(List state, int target, int[] choices, int start, List> res) { + void Backtrack(List state, int target, int[] choices, int start, List> res) { // 子集和等于 target 时,记录解 if (target == 0) { res.Add(new List(state)); @@ -1091,19 +1091,19 @@ comments: true // 尝试:做出选择,更新 target, start state.Add(choices[i]); // 进行下一轮选择 - backtrack(state, target - choices[i], choices, i + 1, res); + Backtrack(state, target - choices[i], choices, i + 1, res); // 回退:撤销选择,恢复到之前的状态 state.RemoveAt(state.Count - 1); } } /* 求解子集和 II */ - List> subsetSumII(int[] nums, int target) { - List state = new List(); // 状态(子集) + List> SubsetSumII(int[] nums, int target) { + List state = new(); // 状态(子集) Array.Sort(nums); // 对 nums 进行排序 int start = 0; // 遍历起始点 - List> res = new List>(); // 结果列表(子集列表) - backtrack(state, target, nums, start, res); + List> res = new(); // 结果列表(子集列表) + Backtrack(state, target, nums, start, res); return res; } ``` diff --git a/zh/chapter_computational_complexity/iteration_and_recursion.md b/zh/chapter_computational_complexity/iteration_and_recursion.md index 909dfcdd5..04a19fd67 100644 --- a/zh/chapter_computational_complexity/iteration_and_recursion.md +++ b/zh/chapter_computational_complexity/iteration_and_recursion.md @@ -61,7 +61,7 @@ status: new ```csharp title="iteration.cs" /* for 循环 */ - int forLoop(int n) { + int ForLoop(int n) { int res = 0; // 循环求和 1, 2, ..., n-1, n for (int i = 1; i <= n; i++) { @@ -239,7 +239,7 @@ status: new ```csharp title="iteration.cs" /* while 循环 */ - int whileLoop(int n) { + int WhileLoop(int n) { int res = 0; int i = 1; // 初始化条件变量 // 循环求和 1, 2, ..., n-1, n @@ -431,7 +431,7 @@ status: new ```csharp title="iteration.cs" /* while 循环(两次更新) */ - int whileLoopII(int n) { + int WhileLoopII(int n) { int res = 0; int i = 1; // 初始化条件变量 // 循环求和 1, 2, 4, 5... @@ -636,8 +636,8 @@ status: new ```csharp title="iteration.cs" /* 双层 for 循环 */ - string nestedForLoop(int n) { - StringBuilder res = new StringBuilder(); + string NestedForLoop(int n) { + StringBuilder res = new(); // 循环 i = 1, 2, ..., n-1, n for (int i = 1; i <= n; i++) { // 循环 j = 1, 2, ..., n-1, n @@ -851,12 +851,12 @@ status: new ```csharp title="recursion.cs" /* 递归 */ - int recur(int n) { + int Recur(int n) { // 终止条件 if (n == 1) return 1; // 递:递归调用 - int res = recur(n - 1); + int res = Recur(n - 1); // 归:返回结果 return n + res; } @@ -1055,12 +1055,12 @@ status: new ```csharp title="recursion.cs" /* 尾递归 */ - int tailRecur(int n, int res) { + int TailRecur(int n, int res) { // 终止条件 if (n == 0) return res; // 尾递归调用 - return tailRecur(n - 1, res + n); + return TailRecur(n - 1, res + n); } ``` @@ -1237,12 +1237,12 @@ status: new ```csharp title="recursion.cs" /* 斐波那契数列:递归 */ - int fib(int n) { + int Fib(int n) { // 终止条件 f(1) = 0, f(2) = 1 if (n == 1 || n == 2) return n - 1; // 递归调用 f(n) = f(n-1) + f(n-2) - int res = fib(n - 1) + fib(n - 2); + int res = Fib(n - 1) + Fib(n - 2); // 返回结果 f(n) return res; } @@ -1471,9 +1471,9 @@ status: new ```csharp title="recursion.cs" /* 使用迭代模拟递归 */ - int forLoopRecur(int n) { + int ForLoopRecur(int n) { // 使用一个显式的栈来模拟系统调用栈 - Stack stack = new Stack(); + Stack stack = new(); int res = 0; // 递:递归调用 for (int i = n; i > 0; i--) { @@ -1493,7 +1493,25 @@ status: new === "Go" ```go title="recursion.go" - [class]{}-[func]{forLoopRecur} + /* 使用迭代模拟递归 */ + func forLoopRecur(n int) int { + // 使用一个显式的栈来模拟系统调用栈 + stack := list.New() + res := 0 + // 递:递归调用 + for i := n; i > 0; i-- { + // 通过“入栈操作”模拟“递” + stack.PushBack(i) + } + // 归:返回结果 + for stack.Len() != 0 { + // 通过“出栈操作”模拟“归” + res += stack.Back().Value.(int) + stack.Remove(stack.Back()) + } + // res = 1+2+3+...+n + return res + } ``` === "Swift" diff --git a/zh/chapter_computational_complexity/space_complexity.md b/zh/chapter_computational_complexity/space_complexity.md index d9724e374..92dba0ce9 100755 --- a/zh/chapter_computational_complexity/space_complexity.md +++ b/zh/chapter_computational_complexity/space_complexity.md @@ -111,16 +111,16 @@ comments: true } /* 函数 */ - int function() { + int Function() { // 执行某些操作... return 0; } - int algorithm(int n) { // 输入数据 + int Algorithm(int n) { // 输入数据 const int a = 0; // 暂存数据(常量) int b = 0; // 暂存数据(变量) - Node node = new Node(0); // 暂存数据(对象) - int c = function(); // 栈帧空间(调用函数) + Node node = new(0); // 暂存数据(对象) + int c = Function(); // 栈帧空间(调用函数) return a + b + c; // 输出数据 } ``` @@ -366,7 +366,7 @@ comments: true === "C#" ```csharp title="" - void algorithm(int n) { + void Algorithm(int n) { int a = 0; // O(1) int[] b = new int[10000]; // O(1) if (n > 10) { @@ -532,20 +532,20 @@ comments: true === "C#" ```csharp title="" - int function() { + int Function() { // 执行某些操作 return 0; } /* 循环 O(1) */ - void loop(int n) { + void Loop(int n) { for (int i = 0; i < n; i++) { - function(); + Function(); } } /* 递归 O(n) */ - int recur(int n) { + int Recur(int n) { if (n == 1) return 1; - return recur(n - 1); + return Recur(n - 1); } ``` @@ -807,25 +807,25 @@ $$ ```csharp title="space_complexity.cs" /* 函数 */ - int function() { + int Function() { // 执行某些操作 return 0; } /* 常数阶 */ - void constant(int n) { + void Constant(int n) { // 常量、变量、对象占用 O(1) 空间 int a = 0; int b = 0; int[] nums = new int[10000]; - ListNode node = new ListNode(0); + ListNode node = new(0); // 循环中的变量占用 O(1) 空间 for (int i = 0; i < n; i++) { int c = 0; } // 循环中的函数占用 O(1) 空间 for (int i = 0; i < n; i++) { - function(); + Function(); } } ``` @@ -1115,7 +1115,7 @@ $$ ```csharp title="space_complexity.cs" /* 线性阶 */ - void linear(int n) { + void Linear(int n) { // 长度为 n 的数组占用 O(n) 空间 int[] nums = new int[n]; // 长度为 n 的列表占用 O(n) 空间 @@ -1361,10 +1361,10 @@ $$ ```csharp title="space_complexity.cs" /* 线性阶(递归实现) */ - void linearRecur(int n) { + void LinearRecur(int n) { Console.WriteLine("递归 n = " + n); if (n == 1) return; - linearRecur(n - 1); + LinearRecur(n - 1); } ``` @@ -1518,7 +1518,7 @@ $$ ```csharp title="space_complexity.cs" /* 平方阶 */ - void quadratic(int n) { + void Quadratic(int n) { // 矩阵占用 O(n^2) 空间 int[,] numMatrix = new int[n, n]; // 二维列表占用 O(n^2) 空间 @@ -1726,11 +1726,11 @@ $$ ```csharp title="space_complexity.cs" /* 平方阶(递归实现) */ - int quadraticRecur(int n) { + int QuadraticRecur(int n) { if (n <= 0) return 0; int[] nums = new int[n]; Console.WriteLine("递归 n = " + n + " 中的 nums 长度 = " + nums.Length); - return quadraticRecur(n - 1); + return QuadraticRecur(n - 1); } ``` @@ -1893,11 +1893,12 @@ $$ ```csharp title="space_complexity.cs" /* 指数阶(建立满二叉树) */ - TreeNode? buildTree(int n) { + TreeNode? BuildTree(int n) { if (n == 0) return null; - TreeNode root = new TreeNode(0); - root.left = buildTree(n - 1); - root.right = buildTree(n - 1); + TreeNode root = new(0) { + left = BuildTree(n - 1), + right = BuildTree(n - 1) + }; return root; } ``` diff --git a/zh/chapter_computational_complexity/time_complexity.md b/zh/chapter_computational_complexity/time_complexity.md index 5f6275126..c163cf6ed 100755 --- a/zh/chapter_computational_complexity/time_complexity.md +++ b/zh/chapter_computational_complexity/time_complexity.md @@ -59,7 +59,7 @@ comments: true ```csharp title="" // 在某运行平台下 - void algorithm(int n) { + void Algorithm(int n) { int a = 2; // 1 ns a = a + 1; // 1 ns a = a * 2; // 10 ns @@ -257,17 +257,17 @@ $$ ```csharp title="" // 算法 A 的时间复杂度:常数阶 - void algorithm_A(int n) { + void AlgorithmA(int n) { Console.WriteLine(0); } // 算法 B 的时间复杂度:线性阶 - void algorithm_B(int n) { + void AlgorithmB(int n) { for (int i = 0; i < n; i++) { Console.WriteLine(0); } } // 算法 C 的时间复杂度:常数阶 - void algorithm_C(int n) { + void AlgorithmC(int n) { for (int i = 0; i < 1000000; i++) { Console.WriteLine(0); } @@ -493,7 +493,7 @@ $$ === "C#" ```csharp title="" - void algorithm(int n) { + void Algorithm(int n) { int a = 1; // +1 a = a + 1; // +1 a = a * 2; // +1 @@ -703,7 +703,7 @@ $T(n)$ 是一次函数,说明其运行时间的增长趋势是线性的,因 === "C#" ```csharp title="" - void algorithm(int n) { + void Algorithm(int n) { int a = 1; // +0(技巧 1) a = a + n; // +0(技巧 1) // +n(技巧 2) @@ -953,7 +953,7 @@ $$ ```csharp title="time_complexity.cs" /* 常数阶 */ - int constant(int n) { + int Constant(int n) { int count = 0; int size = 100000; for (int i = 0; i < size; i++) @@ -1117,7 +1117,7 @@ $$ ```csharp title="time_complexity.cs" /* 线性阶 */ - int linear(int n) { + int Linear(int n) { int count = 0; for (int i = 0; i < n; i++) count++; @@ -1272,7 +1272,7 @@ $$ ```csharp title="time_complexity.cs" /* 线性阶(遍历数组) */ - int arrayTraversal(int[] nums) { + int ArrayTraversal(int[] nums) { int count = 0; // 循环次数与数组长度成正比 foreach (int num in nums) { @@ -1449,7 +1449,7 @@ $$ ```csharp title="time_complexity.cs" /* 平方阶 */ - int quadratic(int n) { + int Quadratic(int n) { int count = 0; // 循环次数与数组长度成平方关系 for (int i = 0; i < n; i++) { @@ -1668,7 +1668,7 @@ $$ ```csharp title="time_complexity.cs" /* 平方阶(冒泡排序) */ - int bubbleSort(int[] nums) { + int BubbleSort(int[] nums) { int count = 0; // 计数器 // 外循环:未排序区间为 [0, i] for (int i = nums.Length - 1; i > 0; i--) { @@ -1933,7 +1933,7 @@ $$ ```csharp title="time_complexity.cs" /* 指数阶(循环实现) */ - int exponential(int n) { + int Exponential(int n) { int count = 0, bas = 1; // 细胞每轮一分为二,形成数列 1, 2, 4, 8, ..., 2^(n-1) for (int i = 0; i < n; i++) { @@ -2141,9 +2141,9 @@ $$ ```csharp title="time_complexity.cs" /* 指数阶(递归实现) */ - int expRecur(int n) { + int ExpRecur(int n) { if (n == 1) return 1; - return expRecur(n - 1) + expRecur(n - 1) + 1; + return ExpRecur(n - 1) + ExpRecur(n - 1) + 1; } ``` @@ -2286,7 +2286,7 @@ $$ ```csharp title="time_complexity.cs" /* 对数阶(循环实现) */ - int logarithmic(float n) { + int Logarithmic(float n) { int count = 0; while (n > 1) { n = n / 2; @@ -2453,9 +2453,9 @@ $$ ```csharp title="time_complexity.cs" /* 对数阶(递归实现) */ - int logRecur(float n) { + int LogRecur(float n) { if (n <= 1) return 0; - return logRecur(n / 2) + 1; + return LogRecur(n / 2) + 1; } ``` @@ -2610,10 +2610,10 @@ $$ ```csharp title="time_complexity.cs" /* 线性对数阶 */ - int linearLogRecur(float n) { + int LinearLogRecur(float n) { if (n <= 1) return 1; - int count = linearLogRecur(n / 2) + - linearLogRecur(n / 2); + int count = LinearLogRecur(n / 2) + + LinearLogRecur(n / 2); for (int i = 0; i < n; i++) { count++; } @@ -2812,12 +2812,12 @@ $$ ```csharp title="time_complexity.cs" /* 阶乘阶(递归实现) */ - int factorialRecur(int n) { + int FactorialRecur(int n) { if (n == 0) return 1; int count = 0; // 从 1 个分裂出 n 个 for (int i = 0; i < n; i++) { - count += factorialRecur(n - 1); + count += FactorialRecur(n - 1); } return count; } @@ -3051,7 +3051,7 @@ $$ ```csharp title="worst_best_time_complexity.cs" /* 生成一个数组,元素为 { 1, 2, ..., n },顺序被打乱 */ - int[] randomNumbers(int n) { + int[] RandomNumbers(int n) { int[] nums = new int[n]; // 生成数组 nums = { 1, 2, 3, ..., n } for (int i = 0; i < n; i++) { @@ -3070,7 +3070,7 @@ $$ } /* 查找数组 nums 中数字 1 所在索引 */ - int findOne(int[] nums) { + int FindOne(int[] nums) { for (int i = 0; i < nums.Length; i++) { // 当元素 1 在数组头部时,达到最佳时间复杂度 O(1) // 当元素 1 在数组尾部时,达到最差时间复杂度 O(n) diff --git a/zh/chapter_divide_and_conquer/binary_search_recur.md b/zh/chapter_divide_and_conquer/binary_search_recur.md index e0cc4496f..feab29242 100644 --- a/zh/chapter_divide_and_conquer/binary_search_recur.md +++ b/zh/chapter_divide_and_conquer/binary_search_recur.md @@ -139,7 +139,7 @@ comments: true ```csharp title="binary_search_recur.cs" /* 二分查找:问题 f(i, j) */ - int dfs(int[] nums, int target, int i, int j) { + int Dfs(int[] nums, int target, int i, int j) { // 若区间为空,代表无目标元素,则返回 -1 if (i > j) { return -1; @@ -148,10 +148,10 @@ comments: true int m = (i + j) / 2; if (nums[m] < target) { // 递归子问题 f(m+1, j) - return dfs(nums, target, m + 1, j); + return Dfs(nums, target, m + 1, j); } else if (nums[m] > target) { // 递归子问题 f(i, m-1) - return dfs(nums, target, i, m - 1); + return Dfs(nums, target, i, m - 1); } else { // 找到目标元素,返回其索引 return m; @@ -159,10 +159,10 @@ comments: true } /* 二分查找 */ - int binarySearch(int[] nums, int target) { + int BinarySearch(int[] nums, int target) { int n = nums.Length; // 求解问题 f(0, n-1) - return dfs(nums, target, 0, n - 1); + return Dfs(nums, target, 0, n - 1); } ``` @@ -354,9 +354,32 @@ comments: true === "C" ```c title="binary_search_recur.c" - [class]{}-[func]{dfs} + /* 二分查找:问题 f(i, j) */ + int dfs(int nums[], int target, int i, int j) { + // 若区间为空,代表无目标元素,则返回 -1 + if (i > j) { + return -1; + } + // 计算中点索引 m + int m = (i + j) / 2; + if (nums[m] < target) { + // 递归子问题 f(m+1, j) + return dfs(nums, target, m + 1, j); + } else if (nums[m] > target) { + // 递归子问题 f(i, m-1) + return dfs(nums, target, i, m - 1); + } else { + // 找到目标元素,返回其索引 + return m; + } + } - [class]{}-[func]{binarySearch} + /* 二分查找 */ + int binarySearch(int nums[], int target, int numsSize) { + int n = numsSize; + // 求解问题 f(0, n-1) + return dfs(nums, target, 0, n - 1); + } ``` === "Zig" diff --git a/zh/chapter_divide_and_conquer/build_binary_tree_problem.md b/zh/chapter_divide_and_conquer/build_binary_tree_problem.md index 81399c23c..a44ca274f 100644 --- a/zh/chapter_divide_and_conquer/build_binary_tree_problem.md +++ b/zh/chapter_divide_and_conquer/build_binary_tree_problem.md @@ -172,30 +172,30 @@ comments: true ```csharp title="build_tree.cs" /* 构建二叉树:分治 */ - TreeNode dfs(int[] preorder, Dictionary inorderMap, int i, int l, int r) { + TreeNode Dfs(int[] preorder, Dictionary inorderMap, int i, int l, int r) { // 子树区间为空时终止 if (r - l < 0) return null; // 初始化根节点 - TreeNode root = new TreeNode(preorder[i]); + TreeNode root = new(preorder[i]); // 查询 m ,从而划分左右子树 int m = inorderMap[preorder[i]]; // 子问题:构建左子树 - root.left = dfs(preorder, inorderMap, i + 1, l, m - 1); + root.left = Dfs(preorder, inorderMap, i + 1, l, m - 1); // 子问题:构建右子树 - root.right = dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r); + root.right = Dfs(preorder, inorderMap, i + 1 + m - l, m + 1, r); // 返回根节点 return root; } /* 构建二叉树 */ - TreeNode buildTree(int[] preorder, int[] inorder) { + TreeNode BuildTree(int[] preorder, int[] inorder) { // 初始化哈希表,存储 inorder 元素到索引的映射 - Dictionary inorderMap = new Dictionary(); + Dictionary inorderMap = new(); for (int i = 0; i < inorder.Length; i++) { inorderMap.TryAdd(inorder[i], i); } - TreeNode root = dfs(preorder, inorderMap, 0, 0, inorder.Length - 1); + TreeNode root = Dfs(preorder, inorderMap, 0, 0, inorder.Length - 1); return root; } ``` diff --git a/zh/chapter_divide_and_conquer/hanota_problem.md b/zh/chapter_divide_and_conquer/hanota_problem.md index 94d76315d..d5dcc2d40 100644 --- a/zh/chapter_divide_and_conquer/hanota_problem.md +++ b/zh/chapter_divide_and_conquer/hanota_problem.md @@ -199,7 +199,7 @@ comments: true ```csharp title="hanota.cs" /* 移动一个圆盘 */ - void move(List src, List tar) { + void Move(List src, List tar) { // 从 src 顶部拿出一个圆盘 int pan = src[^1]; src.RemoveAt(src.Count - 1); @@ -208,25 +208,25 @@ comments: true } /* 求解汉诺塔:问题 f(i) */ - void dfs(int i, List src, List buf, List tar) { + void Dfs(int i, List src, List buf, List tar) { // 若 src 只剩下一个圆盘,则直接将其移到 tar if (i == 1) { - move(src, tar); + Move(src, tar); return; } // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf - dfs(i - 1, src, tar, buf); + Dfs(i - 1, src, tar, buf); // 子问题 f(1) :将 src 剩余一个圆盘移到 tar - move(src, tar); + Move(src, tar); // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar - dfs(i - 1, buf, src, tar); + Dfs(i - 1, buf, src, tar); } /* 求解汉诺塔 */ - void solveHanota(List A, List B, List C) { + void SolveHanota(List A, List B, List C) { int n = A.Count; // 将 A 顶部 n 个圆盘借助 B 移到 C - dfs(n, A, B, C); + Dfs(n, A, B, C); } ``` @@ -440,11 +440,38 @@ comments: true === "C" ```c title="hanota.c" - [class]{}-[func]{move} + /* 移动一个圆盘 */ + void move(vector *src, vector *tar) { + // 从 src 顶部拿出一个圆盘 + int *panTemp = vectorBack(src); + int *pan = malloc(sizeof(int)); + *pan = *panTemp; + vectorPopback(src); + // 将圆盘放入 tar 顶部 + vectorPushback(tar, pan, sizeof(int)); + } - [class]{}-[func]{dfs} + /* 求解汉诺塔:问题 f(i) */ + void dfs(int i, vector *src, vector *buf, vector *tar) { + // 若 src 只剩下一个圆盘,则直接将其移到 tar + if (i == 1) { + move(src, tar); + return; + } + // 子问题 f(i-1) :将 src 顶部 i-1 个圆盘借助 tar 移到 buf + dfs(i - 1, src, tar, buf); + // 子问题 f(1) :将 src 剩余一个圆盘移到 tar + move(src, tar); + // 子问题 f(i-1) :将 buf 顶部 i-1 个圆盘借助 src 移到 tar + dfs(i - 1, buf, src, tar); + } - [class]{}-[func]{solveHanota} + /* 求解汉诺塔 */ + void solveHanota(vector *A, vector *B, vector *C) { + int n = A->size; + // 将 A 顶部 n 个圆盘借助 B 移到 C + dfs(n, A, B, C); + } ``` === "Zig" diff --git a/zh/chapter_dynamic_programming/dp_problem_features.md b/zh/chapter_dynamic_programming/dp_problem_features.md index f213b1341..7a61bed94 100644 --- a/zh/chapter_dynamic_programming/dp_problem_features.md +++ b/zh/chapter_dynamic_programming/dp_problem_features.md @@ -104,7 +104,7 @@ $$ ```csharp title="min_cost_climbing_stairs_dp.cs" /* 爬楼梯最小代价:动态规划 */ - int minCostClimbingStairsDP(int[] cost) { + int MinCostClimbingStairsDP(int[] cost) { int n = cost.Length - 1; if (n == 1 || n == 2) return cost[n]; @@ -130,6 +130,12 @@ $$ if n == 1 || n == 2 { return cost[n] } + min := func(a, b int) int { + if a < b { + return a + } + return b + } // 初始化 dp 表,用于存储子问题的解 dp := make([]int, n+1) // 初始状态:预设最小子问题的解 @@ -137,7 +143,7 @@ $$ dp[2] = cost[2] // 状态转移:从较小子问题逐步求解较大子问题 for i := 3; i <= n; i++ { - dp[i] = int(math.Min(float64(dp[i-1]), float64(dp[i-2]+cost[i]))) + dp[i] = min(dp[i-1], dp[i-2]) + cost[i] } return dp[n] } @@ -252,7 +258,22 @@ $$ === "C" ```c title="min_cost_climbing_stairs_dp.c" - [class]{}-[func]{minCostClimbingStairsDP} + /* 爬楼梯最小代价:动态规划 */ + int minCostClimbingStairsDP(int cost[], int costSize) { + int n = costSize - 1; + if (n == 1 || n == 2) + return cost[n]; + // 初始化 dp 表,用于存储子问题的解 + int dp[n + 1]; + // 初始状态:预设最小子问题的解 + dp[1] = cost[1]; + dp[2] = cost[2]; + // 状态转移:从较小子问题逐步求解较大子问题 + for (int i = 3; i <= n; i++) { + dp[i] = min(dp[i - 1], dp[i - 2]) + cost[i]; + } + return dp[n]; + } ``` === "Zig" @@ -339,7 +360,7 @@ $$ ```csharp title="min_cost_climbing_stairs_dp.cs" /* 爬楼梯最小代价:空间优化后的动态规划 */ - int minCostClimbingStairsDPComp(int[] cost) { + int MinCostClimbingStairsDPComp(int[] cost) { int n = cost.Length - 1; if (n == 1 || n == 2) return cost[n]; @@ -362,12 +383,18 @@ $$ if n == 1 || n == 2 { return cost[n] } + min := func(a, b int) int { + if a < b { + return a + } + return b + } // 初始状态:预设最小子问题的解 a, b := cost[1], cost[2] // 状态转移:从较小子问题逐步求解较大子问题 for i := 3; i <= n; i++ { tmp := b - b = int(math.Min(float64(a), float64(tmp+cost[i]))) + b = min(a, tmp) + cost[i] a = tmp } return b @@ -468,7 +495,19 @@ $$ === "C" ```c title="min_cost_climbing_stairs_dp.c" - [class]{}-[func]{minCostClimbingStairsDPComp} + /* 爬楼梯最小代价:空间优化后的动态规划 */ + int minCostClimbingStairsDPComp(int cost[], int costSize) { + int n = costSize - 1; + if (n == 1 || n == 2) + return cost[n]; + int a = cost[1], b = cost[2]; + for (int i = 3; i <= n; i++) { + int tmp = b; + b = min(a, tmp) + cost[i]; + a = tmp; + } + return b; + } ``` === "Zig" @@ -605,7 +644,7 @@ $$ ```csharp title="climbing_stairs_constraint_dp.cs" /* 带约束爬楼梯:动态规划 */ - int climbingStairsConstraintDP(int n) { + int ClimbingStairsConstraintDP(int n) { if (n == 1 || n == 2) { return 1; } diff --git a/zh/chapter_dynamic_programming/dp_solution_pipeline.md b/zh/chapter_dynamic_programming/dp_solution_pipeline.md index 17e6d2bde..49f325ae0 100644 --- a/zh/chapter_dynamic_programming/dp_solution_pipeline.md +++ b/zh/chapter_dynamic_programming/dp_solution_pipeline.md @@ -174,7 +174,7 @@ $$ ```csharp title="min_path_sum.cs" /* 最小路径和:暴力搜索 */ - int minPathSumDFS(int[][] grid, int i, int j) { + int MinPathSumDFS(int[][] grid, int i, int j) { // 若为左上角单元格,则终止搜索 if (i == 0 && j == 0) { return grid[0][0]; @@ -184,8 +184,8 @@ $$ return int.MaxValue; } // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价 - int left = minPathSumDFS(grid, i - 1, j); - int up = minPathSumDFS(grid, i, j - 1); + int left = MinPathSumDFS(grid, i - 1, j); + int up = MinPathSumDFS(grid, i, j - 1); // 返回从左上角到 (i, j) 的最小路径代价 return Math.Min(left, up) + grid[i][j]; } @@ -325,7 +325,22 @@ $$ === "C" ```c title="min_path_sum.c" - [class]{}-[func]{minPathSumDFS} + /* 最小路径和:暴力搜索 */ + int minPathSumDFS(int gridCols, int grid[][gridCols], int i, int j) { + // 若为左上角单元格,则终止搜索 + if (i == 0 && j == 0) { + return grid[0][0]; + } + // 若行列索引越界,则返回 +∞ 代价 + if (i < 0 || j < 0) { + return INT_MAX; + } + // 计算从左上角到 (i-1, j) 和 (i, j-1) 的最小路径代价 + int left = minPathSumDFS(gridCols, grid, i - 1, j); + int up = minPathSumDFS(gridCols, grid, i, j - 1); + // 返回从左上角到 (i, j) 的最小路径代价 + return min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX; + } ``` === "Zig" @@ -443,7 +458,7 @@ $$ ```csharp title="min_path_sum.cs" /* 最小路径和:记忆化搜索 */ - int minPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) { + int MinPathSumDFSMem(int[][] grid, int[][] mem, int i, int j) { // 若为左上角单元格,则终止搜索 if (i == 0 && j == 0) { return grid[0][0]; @@ -457,8 +472,8 @@ $$ return mem[i][j]; } // 左边和上边单元格的最小路径代价 - int left = minPathSumDFSMem(grid, mem, i - 1, j); - int up = minPathSumDFSMem(grid, mem, i, j - 1); + int left = MinPathSumDFSMem(grid, mem, i - 1, j); + int up = MinPathSumDFSMem(grid, mem, i, j - 1); // 记录并返回左上角到 (i, j) 的最小路径代价 mem[i][j] = Math.Min(left, up) + grid[i][j]; return mem[i][j]; @@ -630,7 +645,27 @@ $$ === "C" ```c title="min_path_sum.c" - [class]{}-[func]{minPathSumDFSMem} + /* 最小路径和:记忆化搜索 */ + int minPathSumDFSMem(int gridCols, int grid[][gridCols], int mem[][gridCols], int i, int j) { + // 若为左上角单元格,则终止搜索 + if (i == 0 && j == 0) { + return grid[0][0]; + } + // 若行列索引越界,则返回 +∞ 代价 + if (i < 0 || j < 0) { + return INT_MAX; + } + // 若已有记录,则直接返回 + if (mem[i][j] != -1) { + return mem[i][j]; + } + // 左边和上边单元格的最小路径代价 + int left = minPathSumDFSMem(gridCols, grid, mem, i - 1, j); + int up = minPathSumDFSMem(gridCols, grid, mem, i, j - 1); + // 记录并返回左上角到 (i, j) 的最小路径代价 + mem[i][j] = min(left, up) != INT_MAX ? min(left, up) + grid[i][j] : INT_MAX; + return mem[i][j]; + } ``` === "Zig" @@ -750,7 +785,7 @@ $$ ```csharp title="min_path_sum.cs" /* 最小路径和:动态规划 */ - int minPathSumDP(int[][] grid) { + int MinPathSumDP(int[][] grid) { int n = grid.Length, m = grid[0].Length; // 初始化 dp 表 int[,] dp = new int[n, m]; @@ -948,7 +983,27 @@ $$ === "C" ```c title="min_path_sum.c" - [class]{}-[func]{minPathSumDP} + /* 最小路径和:动态规划 */ + int minPathSumDP(int gridCols, int grid[][gridCols], int n, int m) { + // 初始化 dp 表 + int dp[n][m]; + dp[0][0] = grid[0][0]; + // 状态转移:首行 + for (int j = 1; j < m; j++) { + dp[0][j] = dp[0][j - 1] + grid[0][j]; + } + // 状态转移:首列 + for (int i = 1; i < n; i++) { + dp[i][0] = dp[i - 1][0] + grid[i][0]; + } + // 状态转移:其余行列 + for (int i = 1; i < n; i++) { + for (int j = 1; j < m; j++) { + dp[i][j] = min(dp[i][j - 1], dp[i - 1][j]) + grid[i][j]; + } + } + return dp[n - 1][m - 1]; + } ``` === "Zig" @@ -1105,7 +1160,7 @@ $$ ```csharp title="min_path_sum.cs" /* 最小路径和:空间优化后的动态规划 */ - int minPathSumDPComp(int[][] grid) { + int MinPathSumDPComp(int[][] grid) { int n = grid.Length, m = grid[0].Length; // 初始化 dp 表 int[] dp = new int[m]; @@ -1288,7 +1343,26 @@ $$ === "C" ```c title="min_path_sum.c" - [class]{}-[func]{minPathSumDPComp} + /* 最小路径和:空间优化后的动态规划 */ + int minPathSumDPComp(int gridCols, int grid[][gridCols], int n, int m) { + // 初始化 dp 表 + int dp[m]; + // 状态转移:首行 + dp[0] = grid[0][0]; + for (int j = 1; j < m; j++) { + dp[j] = dp[j - 1] + grid[0][j]; + } + // 状态转移:其余行 + for (int i = 1; i < n; i++) { + // 状态转移:首列 + dp[0] = dp[0] + grid[i][0]; + // 状态转移:其余列 + for (int j = 1; j < m; j++) { + dp[j] = min(dp[j - 1], dp[j]) + grid[i][j]; + } + } + return dp[m - 1]; + } ``` === "Zig" diff --git a/zh/chapter_dynamic_programming/edit_distance_problem.md b/zh/chapter_dynamic_programming/edit_distance_problem.md index 08e4d5a6f..4e2eac73b 100644 --- a/zh/chapter_dynamic_programming/edit_distance_problem.md +++ b/zh/chapter_dynamic_programming/edit_distance_problem.md @@ -165,7 +165,7 @@ $$ ```csharp title="edit_distance.cs" /* 编辑距离:动态规划 */ - int editDistanceDP(string s, string t) { + int EditDistanceDP(string s, string t) { int n = s.Length, m = t.Length; int[,] dp = new int[n + 1, m + 1]; // 状态转移:首行首列 @@ -578,7 +578,7 @@ $$ ```csharp title="edit_distance.cs" /* 编辑距离:空间优化后的动态规划 */ - int editDistanceDPComp(string s, string t) { + int EditDistanceDPComp(string s, string t) { int n = s.Length, m = t.Length; int[] dp = new int[m + 1]; // 状态转移:首行 diff --git a/zh/chapter_dynamic_programming/intro_to_dynamic_programming.md b/zh/chapter_dynamic_programming/intro_to_dynamic_programming.md index 4ddef50b7..171a75f9a 100644 --- a/zh/chapter_dynamic_programming/intro_to_dynamic_programming.md +++ b/zh/chapter_dynamic_programming/intro_to_dynamic_programming.md @@ -109,7 +109,7 @@ comments: true ```csharp title="climbing_stairs_backtrack.cs" /* 回溯 */ - void backtrack(List choices, int state, int n, List res) { + void Backtrack(List choices, int state, int n, List res) { // 当爬到第 n 阶时,方案数量加 1 if (state == n) res[0]++; @@ -119,17 +119,17 @@ comments: true if (state + choice > n) break; // 尝试:做出选择,更新状态 - backtrack(choices, state + choice, n, res); + Backtrack(choices, state + choice, n, res); // 回退 } } /* 爬楼梯:回溯 */ - int climbingStairsBacktrack(int n) { - List choices = new List { 1, 2 }; // 可选择向上爬 1 或 2 阶 + int ClimbingStairsBacktrack(int n) { + List choices = new() { 1, 2 }; // 可选择向上爬 1 或 2 阶 int state = 0; // 从第 0 阶开始爬 - List res = new List { 0 }; // 使用 res[0] 记录方案数量 - backtrack(choices, state, n, res); + List res = new() { 0 }; // 使用 res[0] 记录方案数量 + Backtrack(choices, state, n, res); return res[0]; } ``` @@ -472,18 +472,18 @@ $$ ```csharp title="climbing_stairs_dfs.cs" /* 搜索 */ - int dfs(int i) { + int Dfs(int i) { // 已知 dp[1] 和 dp[2] ,返回之 if (i == 1 || i == 2) return i; // dp[i] = dp[i-1] + dp[i-2] - int count = dfs(i - 1) + dfs(i - 2); + int count = Dfs(i - 1) + Dfs(i - 2); return count; } /* 爬楼梯:搜索 */ - int climbingStairsDFS(int n) { - return dfs(n); + int ClimbingStairsDFS(int n) { + return Dfs(n); } ``` @@ -736,7 +736,7 @@ $$ ```csharp title="climbing_stairs_dfs_mem.cs" /* 记忆化搜索 */ - int dfs(int i, int[] mem) { + int Dfs(int i, int[] mem) { // 已知 dp[1] 和 dp[2] ,返回之 if (i == 1 || i == 2) return i; @@ -744,18 +744,18 @@ $$ if (mem[i] != -1) return mem[i]; // dp[i] = dp[i-1] + dp[i-2] - int count = dfs(i - 1, mem) + dfs(i - 2, mem); + int count = Dfs(i - 1, mem) + Dfs(i - 2, mem); // 记录 dp[i] mem[i] = count; return count; } /* 爬楼梯:记忆化搜索 */ - int climbingStairsDFSMem(int n) { + int ClimbingStairsDFSMem(int n) { // mem[i] 记录爬到第 i 阶的方案总数,-1 代表无记录 int[] mem = new int[n + 1]; Array.Fill(mem, -1); - return dfs(n, mem); + return Dfs(n, mem); } ``` @@ -1048,7 +1048,7 @@ $$ ```csharp title="climbing_stairs_dp.cs" /* 爬楼梯:动态规划 */ - int climbingStairsDP(int n) { + int ClimbingStairsDP(int n) { if (n == 1 || n == 2) return n; // 初始化 dp 表,用于存储子问题的解 @@ -1296,7 +1296,7 @@ $$ ```csharp title="climbing_stairs_dp.cs" /* 爬楼梯:空间优化后的动态规划 */ - int climbingStairsDPComp(int n) { + int ClimbingStairsDPComp(int n) { if (n == 1 || n == 2) return n; int a = 1, b = 2; diff --git a/zh/chapter_dynamic_programming/knapsack_problem.md b/zh/chapter_dynamic_programming/knapsack_problem.md index 44615cfa0..5d11b04ab 100644 --- a/zh/chapter_dynamic_programming/knapsack_problem.md +++ b/zh/chapter_dynamic_programming/knapsack_problem.md @@ -126,18 +126,18 @@ $$ ```csharp title="knapsack.cs" /* 0-1 背包:暴力搜索 */ - int knapsackDFS(int[] weight, int[] val, int i, int c) { + int KnapsackDFS(int[] weight, int[] val, int i, int c) { // 若已选完所有物品或背包无容量,则返回价值 0 if (i == 0 || c == 0) { return 0; } // 若超过背包容量,则只能不放入背包 if (weight[i - 1] > c) { - return knapsackDFS(weight, val, i - 1, c); + return KnapsackDFS(weight, val, i - 1, c); } // 计算不放入和放入物品 i 的最大价值 - int no = knapsackDFS(weight, val, i - 1, c); - int yes = knapsackDFS(weight, val, i - 1, c - weight[i - 1]) + val[i - 1]; + int no = KnapsackDFS(weight, val, i - 1, c); + int yes = KnapsackDFS(weight, val, i - 1, c - weight[i - 1]) + val[i - 1]; // 返回两种方案中价值更大的那一个 return Math.Max(no, yes); } @@ -277,7 +277,22 @@ $$ === "C" ```c title="knapsack.c" - [class]{}-[func]{knapsackDFS} + /* 0-1 背包:暴力搜索 */ + int knapsackDFS(int wgt[], int val[], int i, int c) { + // 若已选完所有物品或背包无容量,则返回价值 0 + if (i == 0 || c == 0) { + return 0; + } + // 若超过背包容量,则只能不放入背包 + if (wgt[i - 1] > c) { + return knapsackDFS(wgt, val, i - 1, c); + } + // 计算不放入和放入物品 i 的最大价值 + int no = knapsackDFS(wgt, val, i - 1, c); + int yes = knapsackDFS(wgt, val, i - 1, c - wgt[i - 1]) + val[i - 1]; + // 返回两种方案中价值更大的那一个 + return max(no, yes); + } ``` === "Zig" @@ -395,7 +410,7 @@ $$ ```csharp title="knapsack.cs" /* 0-1 背包:记忆化搜索 */ - int knapsackDFSMem(int[] weight, int[] val, int[][] mem, int i, int c) { + int KnapsackDFSMem(int[] weight, int[] val, int[][] mem, int i, int c) { // 若已选完所有物品或背包无容量,则返回价值 0 if (i == 0 || c == 0) { return 0; @@ -406,11 +421,11 @@ $$ } // 若超过背包容量,则只能不放入背包 if (weight[i - 1] > c) { - return knapsackDFSMem(weight, val, mem, i - 1, c); + return KnapsackDFSMem(weight, val, mem, i - 1, c); } // 计算不放入和放入物品 i 的最大价值 - int no = knapsackDFSMem(weight, val, mem, i - 1, c); - int yes = knapsackDFSMem(weight, val, mem, i - 1, c - weight[i - 1]) + val[i - 1]; + int no = KnapsackDFSMem(weight, val, mem, i - 1, c); + int yes = KnapsackDFSMem(weight, val, mem, i - 1, c - weight[i - 1]) + val[i - 1]; // 记录并返回两种方案中价值更大的那一个 mem[i][c] = Math.Max(no, yes); return mem[i][c]; @@ -590,7 +605,27 @@ $$ === "C" ```c title="knapsack.c" - [class]{}-[func]{knapsackDFSMem} + /* 0-1 背包:记忆化搜索 */ + int knapsackDFSMem(int wgt[], int val[], int memCols, int mem[][memCols], int i, int c) { + // 若已选完所有物品或背包无容量,则返回价值 0 + if (i == 0 || c == 0) { + return 0; + } + // 若已有记录,则直接返回 + if (mem[i][c] != -1) { + return mem[i][c]; + } + // 若超过背包容量,则只能不放入背包 + if (wgt[i - 1] > c) { + return knapsackDFSMem(wgt, val, memCols, mem, i - 1, c); + } + // 计算不放入和放入物品 i 的最大价值 + int no = knapsackDFSMem(wgt, val, memCols, mem, i - 1, c); + int yes = knapsackDFSMem(wgt, val, memCols, mem, i - 1, c - wgt[i - 1]) + val[i - 1]; + // 记录并返回两种方案中价值更大的那一个 + mem[i][c] = max(no, yes); + return mem[i][c]; + } ``` === "Zig" @@ -701,7 +736,7 @@ $$ ```csharp title="knapsack.cs" /* 0-1 背包:动态规划 */ - int knapsackDP(int[] weight, int[] val, int cap) { + int KnapsackDP(int[] weight, int[] val, int cap) { int n = weight.Length; // 初始化 dp 表 int[,] dp = new int[n + 1, cap + 1]; @@ -885,7 +920,26 @@ $$ === "C" ```c title="knapsack.c" - [class]{}-[func]{knapsackDP} + /* 0-1 背包:动态规划 */ + int knapsackDP(int wgt[], int val[], int cap, int wgtSize) { + int n = wgtSize; + // 初始化 dp 表 + int dp[n + 1][cap + 1]; + memset(dp, 0, sizeof(dp)); + // 状态转移 + for (int i = 1; i <= n; i++) { + for (int c = 1; c <= cap; c++) { + if (wgt[i - 1] > c) { + // 若超过背包容量,则不选物品 i + dp[i][c] = dp[i - 1][c]; + } else { + // 不选和选物品 i 这两种方案的较大值 + dp[i][c] = max(dp[i - 1][c], dp[i - 1][c - wgt[i - 1]] + val[i - 1]); + } + } + } + return dp[n][cap]; + } ``` === "Zig" @@ -1060,7 +1114,7 @@ $$ ```csharp title="knapsack.cs" /* 0-1 背包:空间优化后的动态规划 */ - int knapsackDPComp(int[] weight, int[] val, int cap) { + int KnapsackDPComp(int[] weight, int[] val, int cap) { int n = weight.Length; // 初始化 dp 表 int[] dp = new int[cap + 1]; @@ -1220,7 +1274,24 @@ $$ === "C" ```c title="knapsack.c" - [class]{}-[func]{knapsackDPComp} + /* 0-1 背包:空间优化后的动态规划 */ + int knapsackDPComp(int wgt[], int val[], int cap, int wgtSize) { + int n = wgtSize; + // 初始化 dp 表 + int dp[cap + 1]; + memset(dp, 0, sizeof(dp)); + // 状态转移 + for (int i = 1; i <= n; i++) { + // 倒序遍历 + for (int c = cap; c >= 1; c--) { + if (wgt[i - 1] <= c) { + // 不选和选物品 i 这两种方案的较大值 + dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]); + } + } + } + return dp[cap]; + } ``` === "Zig" diff --git a/zh/chapter_dynamic_programming/unbounded_knapsack_problem.md b/zh/chapter_dynamic_programming/unbounded_knapsack_problem.md index 7ff818a13..5eca339c0 100644 --- a/zh/chapter_dynamic_programming/unbounded_knapsack_problem.md +++ b/zh/chapter_dynamic_programming/unbounded_knapsack_problem.md @@ -110,7 +110,7 @@ $$ ```csharp title="unbounded_knapsack.cs" /* 完全背包:动态规划 */ - int unboundedKnapsackDP(int[] wgt, int[] val, int cap) { + int UnboundedKnapsackDP(int[] wgt, int[] val, int cap) { int n = wgt.Length; // 初始化 dp 表 int[,] dp = new int[n + 1, cap + 1]; @@ -294,7 +294,26 @@ $$ === "C" ```c title="unbounded_knapsack.c" - [class]{}-[func]{unboundedKnapsackDP} + /* 完全背包:动态规划 */ + int unboundedKnapsackDP(int wgt[], int val[], int cap, int wgtSize) { + int n = wgtSize; + // 初始化 dp 表 + int dp[n + 1][cap + 1]; + memset(dp, 0, sizeof(dp)); + // 状态转移 + for (int i = 1; i <= n; i++) { + for (int c = 1; c <= cap; c++) { + if (wgt[i - 1] > c) { + // 若超过背包容量,则不选物品 i + dp[i][c] = dp[i - 1][c]; + } else { + // 不选和选物品 i 这两种方案的较大值 + dp[i][c] = max(dp[i - 1][c], dp[i][c - wgt[i - 1]] + val[i - 1]); + } + } + } + return dp[n][cap]; + } ``` === "Zig" @@ -422,7 +441,7 @@ $$ ```csharp title="unbounded_knapsack.cs" /* 完全背包:空间优化后的动态规划 */ - int unboundedKnapsackDPComp(int[] wgt, int[] val, int cap) { + int UnboundedKnapsackDPComp(int[] wgt, int[] val, int cap) { int n = wgt.Length; // 初始化 dp 表 int[] dp = new int[cap + 1]; @@ -593,7 +612,26 @@ $$ === "C" ```c title="unbounded_knapsack.c" - [class]{}-[func]{unboundedKnapsackDPComp} + /* 完全背包:空间优化后的动态规划 */ + int unboundedKnapsackDPComp(int wgt[], int val[], int cap, int wgtSize) { + int n = wgtSize; + // 初始化 dp 表 + int dp[cap + 1]; + memset(dp, 0, sizeof(dp)); + // 状态转移 + for (int i = 1; i <= n; i++) { + for (int c = 1; c <= cap; c++) { + if (wgt[i - 1] > c) { + // 若超过背包容量,则不选物品 i + dp[c] = dp[c]; + } else { + // 不选和选物品 i 这两种方案的较大值 + dp[c] = max(dp[c], dp[c - wgt[i - 1]] + val[i - 1]); + } + } + } + return dp[cap]; + } ``` === "Zig" @@ -757,7 +795,7 @@ $$ ```csharp title="coin_change.cs" /* 零钱兑换:动态规划 */ - int coinChangeDP(int[] coins, int amt) { + int CoinChangeDP(int[] coins, int amt) { int n = coins.Length; int MAX = amt + 1; // 初始化 dp 表 @@ -969,7 +1007,31 @@ $$ === "C" ```c title="coin_change.c" - [class]{}-[func]{coinChangeDP} + /* 零钱兑换:动态规划 */ + int coinChangeDP(int coins[], int amt, int coinsSize) { + int n = coinsSize; + int MAX = amt + 1; + // 初始化 dp 表 + int dp[n + 1][amt + 1]; + memset(dp, 0, sizeof(dp)); + // 状态转移:首行首列 + for (int a = 1; a <= amt; a++) { + dp[0][a] = MAX; + } + // 状态转移:其余行列 + for (int i = 1; i <= n; i++) { + for (int a = 1; a <= amt; a++) { + if (coins[i - 1] > a) { + // 若超过背包容量,则不选硬币 i + dp[i][a] = dp[i - 1][a]; + } else { + // 不选和选硬币 i 这两种方案的较小值 + dp[i][a] = min(dp[i - 1][a], dp[i][a - coins[i - 1]] + 1); + } + } + } + return dp[n][amt] != MAX ? dp[n][amt] : -1; + } ``` === "Zig" @@ -1138,7 +1200,7 @@ $$ ```csharp title="coin_change.cs" /* 零钱兑换:空间优化后的动态规划 */ - int coinChangeDPComp(int[] coins, int amt) { + int CoinChangeDPComp(int[] coins, int amt) { int n = coins.Length; int MAX = amt + 1; // 初始化 dp 表 @@ -1327,7 +1389,28 @@ $$ === "C" ```c title="coin_change.c" - [class]{}-[func]{coinChangeDPComp} + /* 零钱兑换:空间优化后的动态规划 */ + int coinChangeDPComp(int coins[], int amt, int coinsSize) { + int n = coinsSize; + int MAX = amt + 1; + // 初始化 dp 表 + int dp[amt + 1]; + memset(dp, MAX, sizeof(dp)); + dp[0] = 0; + // 状态转移 + for (int i = 1; i <= n; i++) { + for (int a = 1; a <= amt; a++) { + if (coins[i - 1] > a) { + // 若超过背包容量,则不选硬币 i + dp[a] = dp[a]; + } else { + // 不选和选硬币 i 这两种方案的较小值 + dp[a] = min(dp[a], dp[a - coins[i - 1]] + 1); + } + } + } + return dp[amt] != MAX ? dp[amt] : -1; + } ``` === "Zig" @@ -1468,7 +1551,7 @@ $$ ```csharp title="coin_change_ii.cs" /* 零钱兑换 II:动态规划 */ - int coinChangeIIDP(int[] coins, int amt) { + int CoinChangeIIDP(int[] coins, int amt) { int n = coins.Length; // 初始化 dp 表 int[,] dp = new int[n + 1, amt + 1]; @@ -1670,7 +1753,30 @@ $$ === "C" ```c title="coin_change_ii.c" - [class]{}-[func]{coinChangeIIDP} + /* 零钱兑换 II:动态规划 */ + int coinChangeIIDP(int coins[], int amt, int coinsSize) { + int n = coinsSize; + // 初始化 dp 表 + int dp[n + 1][amt + 1]; + memset(dp, 0, sizeof(dp)); + // 初始化首列 + for (int i = 0; i <= n; i++) { + dp[i][0] = 1; + } + // 状态转移 + for (int i = 1; i <= n; i++) { + for (int a = 1; a <= amt; a++) { + if (coins[i - 1] > a) { + // 若超过背包容量,则不选硬币 i + dp[i][a] = dp[i - 1][a]; + } else { + // 不选和选硬币 i 这两种方案之和 + dp[i][a] = dp[i - 1][a] + dp[i][a - coins[i - 1]]; + } + } + } + return dp[n][amt]; + } ``` === "Zig" @@ -1781,7 +1887,7 @@ $$ ```csharp title="coin_change_ii.cs" /* 零钱兑换 II:空间优化后的动态规划 */ - int coinChangeIIDPComp(int[] coins, int amt) { + int CoinChangeIIDPComp(int[] coins, int amt) { int n = coins.Length; // 初始化 dp 表 int[] dp = new int[amt + 1]; @@ -1956,7 +2062,27 @@ $$ === "C" ```c title="coin_change_ii.c" - [class]{}-[func]{coinChangeIIDPComp} + /* 零钱兑换 II:空间优化后的动态规划 */ + int coinChangeIIDPComp(int coins[], int amt, int coinsSize) { + int n = coinsSize; + // 初始化 dp 表 + int dp[amt + 1]; + memset(dp, 0, sizeof(dp)); + dp[0] = 1; + // 状态转移 + for (int i = 1; i <= n; i++) { + for (int a = 1; a <= amt; a++) { + if (coins[i - 1] > a) { + // 若超过背包容量,则不选硬币 i + dp[a] = dp[a]; + } else { + // 不选和选硬币 i 这两种方案之和 + dp[a] = dp[a] + dp[a - coins[i - 1]]; + } + } + } + return dp[amt]; + } ``` === "Zig" diff --git a/zh/chapter_graph/graph_operations.md b/zh/chapter_graph/graph_operations.md index 956015e02..c0ff55313 100644 --- a/zh/chapter_graph/graph_operations.md +++ b/zh/chapter_graph/graph_operations.md @@ -294,8 +294,8 @@ comments: true ```csharp title="graph_adjacency_matrix.cs" /* 基于邻接矩阵实现的无向图类 */ class GraphAdjMat { - List vertices; // 顶点列表,元素代表“顶点值”,索引代表“顶点索引” - List> adjMat; // 邻接矩阵,行列索引对应“顶点索引” + readonly List vertices; // 顶点列表,元素代表“顶点值”,索引代表“顶点索引” + readonly List> adjMat; // 邻接矩阵,行列索引对应“顶点索引” /* 构造函数 */ public GraphAdjMat(int[] vertices, int[][] edges) { @@ -303,27 +303,27 @@ comments: true this.adjMat = new List>(); // 添加顶点 foreach (int val in vertices) { - addVertex(val); + AddVertex(val); } // 添加边 // 请注意,edges 元素代表顶点索引,即对应 vertices 元素索引 foreach (int[] e in edges) { - addEdge(e[0], e[1]); + AddEdge(e[0], e[1]); } } /* 获取顶点数量 */ - public int size() { + public int Size() { return vertices.Count; } /* 添加顶点 */ - public void addVertex(int val) { - int n = size(); + public void AddVertex(int val) { + int n = Size(); // 向顶点列表中添加新顶点的值 vertices.Add(val); // 在邻接矩阵中添加一行 - List newRow = new List(n); + List newRow = new(n); for (int j = 0; j < n; j++) { newRow.Add(0); } @@ -335,8 +335,8 @@ comments: true } /* 删除顶点 */ - public void removeVertex(int index) { - if (index >= size()) + public void RemoveVertex(int index) { + if (index >= Size()) throw new IndexOutOfRangeException(); // 在顶点列表中移除索引 index 的顶点 vertices.RemoveAt(index); @@ -350,9 +350,9 @@ comments: true /* 添加边 */ // 参数 i, j 对应 vertices 元素索引 - public void addEdge(int i, int j) { + public void AddEdge(int i, int j) { // 索引越界与相等处理 - if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) + if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j) throw new IndexOutOfRangeException(); // 在无向图中,邻接矩阵沿主对角线对称,即满足 (i, j) == (j, i) adjMat[i][j] = 1; @@ -361,16 +361,16 @@ comments: true /* 删除边 */ // 参数 i, j 对应 vertices 元素索引 - public void removeEdge(int i, int j) { + public void RemoveEdge(int i, int j) { // 索引越界与相等处理 - if (i < 0 || j < 0 || i >= size() || j >= size() || i == j) + if (i < 0 || j < 0 || i >= Size() || j >= Size() || i == j) throw new IndexOutOfRangeException(); adjMat[i][j] = 0; adjMat[j][i] = 0; } /* 打印邻接矩阵 */ - public void print() { + public void Print() { Console.Write("顶点列表 = "); PrintUtil.PrintList(vertices); Console.WriteLine("邻接矩阵 ="); @@ -1390,19 +1390,19 @@ comments: true this.adjList = new Dictionary>(); // 添加所有顶点和边 foreach (Vertex[] edge in edges) { - addVertex(edge[0]); - addVertex(edge[1]); - addEdge(edge[0], edge[1]); + AddVertex(edge[0]); + AddVertex(edge[1]); + AddEdge(edge[0], edge[1]); } } /* 获取顶点数量 */ - public int size() { + public int Size() { return adjList.Count; } /* 添加边 */ - public void addEdge(Vertex vet1, Vertex vet2) { + public void AddEdge(Vertex vet1, Vertex vet2) { if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2) throw new InvalidOperationException(); // 添加边 vet1 - vet2 @@ -1411,7 +1411,7 @@ comments: true } /* 删除边 */ - public void removeEdge(Vertex vet1, Vertex vet2) { + public void RemoveEdge(Vertex vet1, Vertex vet2) { if (!adjList.ContainsKey(vet1) || !adjList.ContainsKey(vet2) || vet1 == vet2) throw new InvalidOperationException(); // 删除边 vet1 - vet2 @@ -1420,7 +1420,7 @@ comments: true } /* 添加顶点 */ - public void addVertex(Vertex vet) { + public void AddVertex(Vertex vet) { if (adjList.ContainsKey(vet)) return; // 在邻接表中添加一个新链表 @@ -1428,7 +1428,7 @@ comments: true } /* 删除顶点 */ - public void removeVertex(Vertex vet) { + public void RemoveVertex(Vertex vet) { if (!adjList.ContainsKey(vet)) throw new InvalidOperationException(); // 在邻接表中删除顶点 vet 对应的链表 @@ -1440,10 +1440,10 @@ comments: true } /* 打印邻接表 */ - public void print() { + public void Print() { Console.WriteLine("邻接表 ="); foreach (KeyValuePair> pair in adjList) { - List tmp = new List(); + List tmp = new(); foreach (Vertex vertex in pair.Value) tmp.Add(vertex.val); Console.WriteLine(pair.Key.val + ": [" + string.Join(", ", tmp) + "],"); diff --git a/zh/chapter_graph/graph_traversal.md b/zh/chapter_graph/graph_traversal.md index 0d30b114d..f396ab5c4 100644 --- a/zh/chapter_graph/graph_traversal.md +++ b/zh/chapter_graph/graph_traversal.md @@ -119,13 +119,13 @@ BFS 通常借助队列来实现。队列具有“先入先出”的性质,这 ```csharp title="graph_bfs.cs" /* 广度优先遍历 BFS */ // 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 - List graphBFS(GraphAdjList graph, Vertex startVet) { + List GraphBFS(GraphAdjList graph, Vertex startVet) { // 顶点遍历序列 - List res = new List(); + List res = new(); // 哈希表,用于记录已被访问过的顶点 - HashSet visited = new HashSet() { startVet }; + HashSet visited = new() { startVet }; // 队列用于实现 BFS - Queue que = new Queue(); + Queue que = new(); que.Enqueue(startVet); // 以顶点 vet 为起点,循环直至访问完所有顶点 while (que.Count > 0) { @@ -532,7 +532,7 @@ BFS 通常借助队列来实现。队列具有“先入先出”的性质,这 ```csharp title="graph_dfs.cs" /* 深度优先遍历 DFS 辅助函数 */ - void dfs(GraphAdjList graph, HashSet visited, List res, Vertex vet) { + void Dfs(GraphAdjList graph, HashSet visited, List res, Vertex vet) { res.Add(vet); // 记录访问顶点 visited.Add(vet); // 标记该顶点已被访问 // 遍历该顶点的所有邻接顶点 @@ -541,18 +541,18 @@ BFS 通常借助队列来实现。队列具有“先入先出”的性质,这 continue; // 跳过已被访问过的顶点 } // 递归访问邻接顶点 - dfs(graph, visited, res, adjVet); + Dfs(graph, visited, res, adjVet); } } /* 深度优先遍历 DFS */ // 使用邻接表来表示图,以便获取指定顶点的所有邻接顶点 - List graphDFS(GraphAdjList graph, Vertex startVet) { + List GraphDFS(GraphAdjList graph, Vertex startVet) { // 顶点遍历序列 - List res = new List(); + List res = new(); // 哈希表,用于记录已被访问过的顶点 - HashSet visited = new HashSet(); - dfs(graph, visited, res, startVet); + HashSet visited = new(); + Dfs(graph, visited, res, startVet); return res; } ``` diff --git a/zh/chapter_greedy/fractional_knapsack_problem.md b/zh/chapter_greedy/fractional_knapsack_problem.md index fadcaf2a3..ed6bd778d 100644 --- a/zh/chapter_greedy/fractional_knapsack_problem.md +++ b/zh/chapter_greedy/fractional_knapsack_problem.md @@ -166,7 +166,7 @@ comments: true } /* 分数背包:贪心 */ - double fractionalKnapsack(int[] wgt, int[] val, int cap) { + double FractionalKnapsack(int[] wgt, int[] val, int cap) { // 创建物品列表,包含两个属性:重量、价值 Item[] items = new Item[wgt.Length]; for (int i = 0; i < wgt.Length; i++) { diff --git a/zh/chapter_greedy/greedy_algorithm.md b/zh/chapter_greedy/greedy_algorithm.md index c92ea0c5d..8b489bc54 100644 --- a/zh/chapter_greedy/greedy_algorithm.md +++ b/zh/chapter_greedy/greedy_algorithm.md @@ -95,7 +95,7 @@ comments: true ```csharp title="coin_change_greedy.cs" /* 零钱兑换:贪心 */ - int coinChangeGreedy(int[] coins, int amt) { + int CoinChangeGreedy(int[] coins, int amt) { // 假设 coins 列表有序 int i = coins.Length - 1; int count = 0; diff --git a/zh/chapter_greedy/max_capacity_problem.md b/zh/chapter_greedy/max_capacity_problem.md index 47d46b158..afa8b26ff 100644 --- a/zh/chapter_greedy/max_capacity_problem.md +++ b/zh/chapter_greedy/max_capacity_problem.md @@ -168,7 +168,7 @@ $$ ```csharp title="max_capacity.cs" /* 最大容量:贪心 */ - int maxCapacity(int[] ht) { + int MaxCapacity(int[] ht) { // 初始化 i, j 分列数组两端 int i = 0, j = ht.Length - 1; // 初始最大容量为 0 diff --git a/zh/chapter_greedy/max_product_cutting_problem.md b/zh/chapter_greedy/max_product_cutting_problem.md index 570bfdf98..a5c9126be 100644 --- a/zh/chapter_greedy/max_product_cutting_problem.md +++ b/zh/chapter_greedy/max_product_cutting_problem.md @@ -147,7 +147,7 @@ $$ ```csharp title="max_product_cutting.cs" /* 最大切分乘积:贪心 */ - int maxProductCutting(int n) { + int MaxProductCutting(int n) { // 当 n <= 3 时,必须切分出一个 1 if (n <= 3) { return 1 * (n - 1); diff --git a/zh/chapter_hashing/hash_algorithm.md b/zh/chapter_hashing/hash_algorithm.md index 927ae76f3..9496bc695 100644 --- a/zh/chapter_hashing/hash_algorithm.md +++ b/zh/chapter_hashing/hash_algorithm.md @@ -180,7 +180,7 @@ index = hash(key) % capacity ```csharp title="simple_hash.cs" /* 加法哈希 */ - int addHash(string key) { + int AddHash(string key) { long hash = 0; const int MODULUS = 1000000007; foreach (char c in key) { @@ -190,7 +190,7 @@ index = hash(key) % capacity } /* 乘法哈希 */ - int mulHash(string key) { + int MulHash(string key) { long hash = 0; const int MODULUS = 1000000007; foreach (char c in key) { @@ -200,7 +200,7 @@ index = hash(key) % capacity } /* 异或哈希 */ - int xorHash(string key) { + int XorHash(string key) { int hash = 0; const int MODULUS = 1000000007; foreach (char c in key) { @@ -210,7 +210,7 @@ index = hash(key) % capacity } /* 旋转哈希 */ - int rotHash(string key) { + int RotHash(string key) { long hash = 0; const int MODULUS = 1000000007; foreach (char c in key) { @@ -735,7 +735,7 @@ $$ int hashTup = arr.GetHashCode(); // 数组 [12836, 小哈] 的哈希值为 42931033; - ListNode obj = new ListNode(0); + ListNode obj = new(0); int hashObj = obj.GetHashCode(); // 节点对象 0 的哈希值为 39053774; ``` diff --git a/zh/chapter_hashing/hash_collision.md b/zh/chapter_hashing/hash_collision.md index a375d0284..b42a8817c 100644 --- a/zh/chapter_hashing/hash_collision.md +++ b/zh/chapter_hashing/hash_collision.md @@ -359,8 +359,8 @@ comments: true class HashMapChaining { int size; // 键值对数量 int capacity; // 哈希表容量 - double loadThres; // 触发扩容的负载因子阈值 - int extendRatio; // 扩容倍数 + readonly double loadThres; // 触发扩容的负载因子阈值 + readonly int extendRatio; // 扩容倍数 List> buckets; // 桶数组 /* 构造方法 */ @@ -376,18 +376,18 @@ comments: true } /* 哈希函数 */ - private int hashFunc(int key) { + private int HashFunc(int key) { return key % capacity; } /* 负载因子 */ - private double loadFactor() { + private double LoadFactor() { return (double)size / capacity; } /* 查询操作 */ - public string? get(int key) { - int index = hashFunc(key); + public string? Get(int key) { + int index = HashFunc(key); // 遍历桶,若找到 key 则返回对应 val foreach (Pair pair in buckets[index]) { if (pair.key == key) { @@ -399,12 +399,12 @@ comments: true } /* 添加操作 */ - public void put(int key, string val) { + public void Put(int key, string val) { // 当负载因子超过阈值时,执行扩容 - if (loadFactor() > loadThres) { - extend(); + if (LoadFactor() > loadThres) { + Extend(); } - int index = hashFunc(key); + int index = HashFunc(key); // 遍历桶,若遇到指定 key ,则更新对应 val 并返回 foreach (Pair pair in buckets[index]) { if (pair.key == key) { @@ -418,8 +418,8 @@ comments: true } /* 删除操作 */ - public void remove(int key) { - int index = hashFunc(key); + public void Remove(int key) { + int index = HashFunc(key); // 遍历桶,从中删除键值对 foreach (Pair pair in buckets[index].ToList()) { if (pair.key == key) { @@ -431,7 +431,7 @@ comments: true } /* 扩容哈希表 */ - private void extend() { + private void Extend() { // 暂存原哈希表 List> bucketsTmp = buckets; // 初始化扩容后的新哈希表 @@ -444,15 +444,15 @@ comments: true // 将键值对从原哈希表搬运至新哈希表 foreach (List bucket in bucketsTmp) { foreach (Pair pair in bucket) { - put(pair.key, pair.val); + Put(pair.key, pair.val); } } } /* 打印哈希表 */ - public void print() { + public void Print() { foreach (List bucket in buckets) { - List res = new List(); + List res = new(); foreach (Pair pair in bucket) { res.Add(pair.key + " -> " + pair.val); } @@ -1743,10 +1743,10 @@ comments: true class HashMapOpenAddressing { private int size; // 键值对数量 private int capacity = 4; // 哈希表容量 - private double loadThres = 2.0 / 3.0; // 触发扩容的负载因子阈值 - private int extendRatio = 2; // 扩容倍数 + private readonly double loadThres = 2.0 / 3.0; // 触发扩容的负载因子阈值 + private readonly int extendRatio = 2; // 扩容倍数 private Pair[] buckets; // 桶数组 - private Pair TOMBSTONE = new Pair(-1, "-1"); // 删除标记 + private readonly Pair TOMBSTONE = new(-1, "-1"); // 删除标记 /* 构造方法 */ public HashMapOpenAddressing() { @@ -1755,18 +1755,18 @@ comments: true } /* 哈希函数 */ - private int hashFunc(int key) { + private int HashFunc(int key) { return key % capacity; } /* 负载因子 */ - private double loadFactor() { + private double LoadFactor() { return (double)size / capacity; } /* 搜索 key 对应的桶索引 */ - private int findBucket(int key) { - int index = hashFunc(key); + private int FindBucket(int key) { + int index = HashFunc(key); int firstTombstone = -1; // 线性探测,当遇到空桶时跳出 while (buckets[index] != null) { @@ -1792,9 +1792,9 @@ comments: true } /* 查询操作 */ - public string? get(int key) { + public string? Get(int key) { // 搜索 key 对应的桶索引 - int index = findBucket(key); + int index = FindBucket(key); // 若找到键值对,则返回对应 val if (buckets[index] != null && buckets[index] != TOMBSTONE) { return buckets[index].val; @@ -1804,13 +1804,13 @@ comments: true } /* 添加操作 */ - public void put(int key, string val) { + public void Put(int key, string val) { // 当负载因子超过阈值时,执行扩容 - if (loadFactor() > loadThres) { - extend(); + if (LoadFactor() > loadThres) { + Extend(); } // 搜索 key 对应的桶索引 - int index = findBucket(key); + int index = FindBucket(key); // 若找到键值对,则覆盖 val 并返回 if (buckets[index] != null && buckets[index] != TOMBSTONE) { buckets[index].val = val; @@ -1822,9 +1822,9 @@ comments: true } /* 删除操作 */ - public void remove(int key) { + public void Remove(int key) { // 搜索 key 对应的桶索引 - int index = findBucket(key); + int index = FindBucket(key); // 若找到键值对,则用删除标记覆盖它 if (buckets[index] != null && buckets[index] != TOMBSTONE) { buckets[index] = TOMBSTONE; @@ -1833,7 +1833,7 @@ comments: true } /* 扩容哈希表 */ - private void extend() { + private void Extend() { // 暂存原哈希表 Pair[] bucketsTmp = buckets; // 初始化扩容后的新哈希表 @@ -1843,13 +1843,13 @@ comments: true // 将键值对从原哈希表搬运至新哈希表 foreach (Pair pair in bucketsTmp) { if (pair != null && pair != TOMBSTONE) { - put(pair.key, pair.val); + Put(pair.key, pair.val); } } } /* 打印哈希表 */ - public void print() { + public void Print() { foreach (Pair pair in buckets) { if (pair == null) { Console.WriteLine("null"); diff --git a/zh/chapter_hashing/hash_map.md b/zh/chapter_hashing/hash_map.md index 8e09e6724..ade653731 100755 --- a/zh/chapter_hashing/hash_map.md +++ b/zh/chapter_hashing/hash_map.md @@ -109,19 +109,19 @@ comments: true ```csharp title="hash_map.cs" /* 初始化哈希表 */ - Dictionary map = new (); - - /* 添加操作 */ - // 在哈希表中添加键值对 (key, value) - map.Add(12836, "小哈"); - map.Add(15937, "小啰"); - map.Add(16750, "小算"); - map.Add(13276, "小法"); - map.Add(10583, "小鸭"); + Dictionary map = new() { + /* 添加操作 */ + // 在哈希表中添加键值对 (key, value) + { 12836, "小哈" }, + { 15937, "小啰" }, + { 16750, "小算" }, + { 13276, "小法" }, + { 10583, "小鸭" } + }; /* 查询操作 */ // 向哈希表输入键 key ,得到值 value - String name = map[15937]; + string name = map[15937]; /* 删除操作 */ // 在哈希表中删除键值对 (key, value) @@ -791,7 +791,7 @@ index = hash(key) % capacity /* 基于数组简易实现的哈希表 */ class ArrayHashMap { - private List buckets; + private readonly List buckets; public ArrayHashMap() { // 初始化数组,包含 100 个桶 buckets = new(); @@ -801,35 +801,35 @@ index = hash(key) % capacity } /* 哈希函数 */ - private int hashFunc(int key) { + private int HashFunc(int key) { int index = key % 100; return index; } /* 查询操作 */ - public string? get(int key) { - int index = hashFunc(key); + public string? Get(int key) { + int index = HashFunc(key); Pair? pair = buckets[index]; if (pair == null) return null; return pair.val; } /* 添加操作 */ - public void put(int key, string val) { - Pair pair = new Pair(key, val); - int index = hashFunc(key); + public void Put(int key, string val) { + Pair pair = new(key, val); + int index = HashFunc(key); buckets[index] = pair; } /* 删除操作 */ - public void remove(int key) { - int index = hashFunc(key); + public void Remove(int key) { + int index = HashFunc(key); // 置为 null ,代表删除 buckets[index] = null; } /* 获取所有键值对 */ - public List pairSet() { + public List PairSet() { List pairSet = new(); foreach (Pair? pair in buckets) { if (pair != null) @@ -839,7 +839,7 @@ index = hash(key) % capacity } /* 获取所有键 */ - public List keySet() { + public List KeySet() { List keySet = new(); foreach (Pair? pair in buckets) { if (pair != null) @@ -849,7 +849,7 @@ index = hash(key) % capacity } /* 获取所有值 */ - public List valueSet() { + public List ValueSet() { List valueSet = new(); foreach (Pair? pair in buckets) { if (pair != null) @@ -859,8 +859,8 @@ index = hash(key) % capacity } /* 打印哈希表 */ - public void print() { - foreach (Pair kv in pairSet()) { + public void Print() { + foreach (Pair kv in PairSet()) { Console.WriteLine(kv.key + " -> " + kv.val); } } diff --git a/zh/chapter_heap/build_heap.md b/zh/chapter_heap/build_heap.md index aed127200..075251406 100644 --- a/zh/chapter_heap/build_heap.md +++ b/zh/chapter_heap/build_heap.md @@ -75,9 +75,9 @@ comments: true // 将列表元素原封不动添加进堆 maxHeap = new List(nums); // 堆化除叶节点以外的其他所有节点 - var size = parent(this.size() - 1); + var size = Parent(this.Size() - 1); for (int i = size; i >= 0; i--) { - siftDown(i); + SiftDown(i); } } ``` diff --git a/zh/chapter_heap/heap.md b/zh/chapter_heap/heap.md index 4dfca5035..3b5eb9197 100644 --- a/zh/chapter_heap/heap.md +++ b/zh/chapter_heap/heap.md @@ -168,9 +168,9 @@ comments: true ```csharp title="heap.cs" /* 初始化堆 */ // 初始化小顶堆 - PriorityQueue minHeap = new PriorityQueue(); + PriorityQueue minHeap = new(); // 初始化大顶堆(使用 lambda 表达式修改 Comparator 即可) - PriorityQueue maxHeap = new PriorityQueue(Comparer.Create((x, y) => y - x)); + PriorityQueue maxHeap = new(Comparer.Create((x, y) => y - x)); /* 元素入堆 */ maxHeap.Enqueue(1, 1); @@ -431,17 +431,17 @@ comments: true ```csharp title="my_heap.cs" /* 获取左子节点索引 */ - int left(int i) { + int Left(int i) { return 2 * i + 1; } /* 获取右子节点索引 */ - int right(int i) { + int Right(int i) { return 2 * i + 2; } /* 获取父节点索引 */ - int parent(int i) { + int Parent(int i) { return (i - 1) / 2; // 向下整除 } ``` @@ -634,7 +634,7 @@ comments: true ```csharp title="my_heap.cs" /* 访问堆顶元素 */ - int peek() { + int Peek() { return maxHeap[0]; } ``` @@ -830,23 +830,23 @@ comments: true ```csharp title="my_heap.cs" /* 元素入堆 */ - void push(int val) { + void Push(int val) { // 添加节点 maxHeap.Add(val); // 从底至顶堆化 - siftUp(size() - 1); + SiftUp(Size() - 1); } /* 从节点 i 开始,从底至顶堆化 */ - void siftUp(int i) { + void SiftUp(int i) { while (true) { // 获取节点 i 的父节点 - int p = parent(i); + int p = Parent(i); // 若“越过根节点”或“节点无须修复”,则结束堆化 if (p < 0 || maxHeap[i] <= maxHeap[p]) break; // 交换两节点 - swap(i, p); + Swap(i, p); // 循环向上堆化 i = p; } @@ -1241,34 +1241,34 @@ comments: true ```csharp title="my_heap.cs" /* 元素出堆 */ - int pop() { + int Pop() { // 判空处理 - if (isEmpty()) + if (IsEmpty()) throw new IndexOutOfRangeException(); // 交换根节点与最右叶节点(即交换首元素与尾元素) - swap(0, size() - 1); + Swap(0, Size() - 1); // 删除节点 int val = maxHeap.Last(); - maxHeap.RemoveAt(size() - 1); + maxHeap.RemoveAt(Size() - 1); // 从顶至底堆化 - siftDown(0); + SiftDown(0); // 返回堆顶元素 return val; } /* 从节点 i 开始,从顶至底堆化 */ - void siftDown(int i) { + void SiftDown(int i) { while (true) { // 判断节点 i, l, r 中值最大的节点,记为 ma - int l = left(i), r = right(i), ma = i; - if (l < size() && maxHeap[l] > maxHeap[ma]) + int l = Left(i), r = Right(i), ma = i; + if (l < Size() && maxHeap[l] > maxHeap[ma]) ma = l; - if (r < size() && maxHeap[r] > maxHeap[ma]) + if (r < Size() && maxHeap[r] > maxHeap[ma]) ma = r; // 若“节点 i 最大”或“越过叶节点”,则结束堆化 if (ma == i) break; // 交换两节点 - swap(i, ma); + Swap(i, ma); // 循环向下堆化 i = ma; } diff --git a/zh/chapter_heap/top_k.md b/zh/chapter_heap/top_k.md index f03169eb9..30155aa03 100644 --- a/zh/chapter_heap/top_k.md +++ b/zh/chapter_heap/top_k.md @@ -142,8 +142,8 @@ comments: true ```csharp title="top_k.cs" /* 基于堆查找数组中最大的 k 个元素 */ - PriorityQueue topKHeap(int[] nums, int k) { - PriorityQueue heap = new PriorityQueue(); + PriorityQueue TopKHeap(int[] nums, int k) { + PriorityQueue heap = new(); // 将数组的前 k 个元素入堆 for (int i = 0; i < k; i++) { heap.Enqueue(nums[i], nums[i]); diff --git a/zh/chapter_searching/binary_search.md b/zh/chapter_searching/binary_search.md index a41018976..a02120f57 100755 --- a/zh/chapter_searching/binary_search.md +++ b/zh/chapter_searching/binary_search.md @@ -119,7 +119,7 @@ comments: true ```csharp title="binary_search.cs" /* 二分查找(双闭区间) */ - int binarySearch(int[] nums, int target) { + int BinarySearch(int[] nums, int target) { // 初始化双闭区间 [0, n-1] ,即 i, j 分别指向数组首元素、尾元素 int i = 0, j = nums.Length - 1; // 循环,当搜索区间为空时跳出(当 i > j 时为空) @@ -409,7 +409,7 @@ comments: true ```csharp title="binary_search.cs" /* 二分查找(左闭右开) */ - int binarySearchLCRO(int[] nums, int target) { + int BinarySearchLCRO(int[] nums, int target) { // 初始化左闭右开 [0, n) ,即 i, j 分别指向数组首元素、尾元素+1 int i = 0, j = nums.Length; // 循环,当搜索区间为空时跳出(当 i = j 时为空) diff --git a/zh/chapter_searching/binary_search_edge.md b/zh/chapter_searching/binary_search_edge.md index 9c63d81fa..6074dec41 100644 --- a/zh/chapter_searching/binary_search_edge.md +++ b/zh/chapter_searching/binary_search_edge.md @@ -69,9 +69,9 @@ comments: true ```csharp title="binary_search_edge.cs" /* 二分查找最左一个 target */ - int binarySearchLeftEdge(int[] nums, int target) { + int BinarySearchLeftEdge(int[] nums, int target) { // 等价于查找 target 的插入点 - int i = binary_search_insertion.binarySearchInsertion(nums, target); + int i = binary_search_insertion.BinarySearchInsertion(nums, target); // 未找到 target ,返回 -1 if (i == nums.Length || nums[i] != target) { return -1; @@ -273,9 +273,9 @@ comments: true ```csharp title="binary_search_edge.cs" /* 二分查找最右一个 target */ - int binarySearchRightEdge(int[] nums, int target) { + int BinarySearchRightEdge(int[] nums, int target) { // 转化为查找最左一个 target + 1 - int i = binary_search_insertion.binarySearchInsertion(nums, target + 1); + int i = binary_search_insertion.BinarySearchInsertion(nums, target + 1); // j 指向最右一个 target ,i 指向首个大于 target 的元素 int j = i - 1; // 未找到 target ,返回 -1 diff --git a/zh/chapter_searching/binary_search_insertion.md b/zh/chapter_searching/binary_search_insertion.md index 8ec04f5fe..ae183062f 100644 --- a/zh/chapter_searching/binary_search_insertion.md +++ b/zh/chapter_searching/binary_search_insertion.md @@ -92,7 +92,7 @@ comments: true ```csharp title="binary_search_insertion.cs" /* 二分查找插入点(无重复元素) */ - int binarySearchInsertionSimple(int[] nums, int target) { + int BinarySearchInsertionSimple(int[] nums, int target) { int i = 0, j = nums.Length - 1; // 初始化双闭区间 [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // 计算中点索引 m @@ -392,7 +392,7 @@ comments: true ```csharp title="binary_search_insertion.cs" /* 二分查找插入点(存在重复元素) */ - int binarySearchInsertion(int[] nums, int target) { + int BinarySearchInsertion(int[] nums, int target) { int i = 0, j = nums.Length - 1; // 初始化双闭区间 [0, n-1] while (i <= j) { int m = i + (j - i) / 2; // 计算中点索引 m diff --git a/zh/chapter_searching/replace_linear_by_hashing.md b/zh/chapter_searching/replace_linear_by_hashing.md index a9640f436..915e7209b 100755 --- a/zh/chapter_searching/replace_linear_by_hashing.md +++ b/zh/chapter_searching/replace_linear_by_hashing.md @@ -69,7 +69,7 @@ comments: true ```csharp title="two_sum.cs" /* 方法一:暴力枚举 */ - int[] twoSumBruteForce(int[] nums, int target) { + int[] TwoSumBruteForce(int[] nums, int target) { int size = nums.Length; // 两层循环,时间复杂度 O(n^2) for (int i = 0; i < size - 1; i++) { @@ -306,7 +306,7 @@ comments: true ```csharp title="two_sum.cs" /* 方法二:辅助哈希表 */ - int[] twoSumHashTable(int[] nums, int target) { + int[] TwoSumHashTable(int[] nums, int target) { int size = nums.Length; // 辅助哈希表,空间复杂度 O(n) Dictionary dic = new(); diff --git a/zh/chapter_sorting/bubble_sort.md b/zh/chapter_sorting/bubble_sort.md index 414b005cd..8e9053311 100755 --- a/zh/chapter_sorting/bubble_sort.md +++ b/zh/chapter_sorting/bubble_sort.md @@ -102,16 +102,14 @@ comments: true ```csharp title="bubble_sort.cs" /* 冒泡排序 */ - void bubbleSort(int[] nums) { + void BubbleSort(int[] nums) { // 外循环:未排序区间为 [0, i] for (int i = nums.Length - 1; i > 0; i--) { // 内循环:将未排序区间 [0, i] 中的最大元素交换至该区间的最右端 for (int j = 0; j < i; j++) { if (nums[j] > nums[j + 1]) { // 交换 nums[j] 与 nums[j + 1] - int tmp = nums[j]; - nums[j] = nums[j + 1]; - nums[j + 1] = tmp; + (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]); } } } @@ -353,7 +351,7 @@ comments: true ```csharp title="bubble_sort.cs" /* 冒泡排序(标志优化)*/ - void bubbleSortWithFlag(int[] nums) { + void BubbleSortWithFlag(int[] nums) { // 外循环:未排序区间为 [0, i] for (int i = nums.Length - 1; i > 0; i--) { bool flag = false; // 初始化标志位 @@ -361,9 +359,7 @@ comments: true for (int j = 0; j < i; j++) { if (nums[j] > nums[j + 1]) { // 交换 nums[j] 与 nums[j + 1] - int tmp = nums[j]; - nums[j] = nums[j + 1]; - nums[j + 1] = tmp; + (nums[j + 1], nums[j]) = (nums[j], nums[j + 1]); flag = true; // 记录交换元素 } } diff --git a/zh/chapter_sorting/bucket_sort.md b/zh/chapter_sorting/bucket_sort.md index 341ecbbcb..007b9f9cb 100644 --- a/zh/chapter_sorting/bucket_sort.md +++ b/zh/chapter_sorting/bucket_sort.md @@ -113,10 +113,10 @@ comments: true ```csharp title="bucket_sort.cs" /* 桶排序 */ - void bucketSort(float[] nums) { + void BucketSort(float[] nums) { // 初始化 k = n/2 个桶,预期向每个桶分配 2 个元素 int k = nums.Length / 2; - List> buckets = new List>(); + List> buckets = new(); for (int i = 0; i < k; i++) { buckets.Add(new List()); } diff --git a/zh/chapter_sorting/counting_sort.md b/zh/chapter_sorting/counting_sort.md index bcf0ae42b..26f784c52 100644 --- a/zh/chapter_sorting/counting_sort.md +++ b/zh/chapter_sorting/counting_sort.md @@ -100,7 +100,7 @@ comments: true ```csharp title="counting_sort.cs" /* 计数排序 */ // 简单实现,无法用于排序对象 - void countingSortNaive(int[] nums) { + void CountingSortNaive(int[] nums) { // 1. 统计数组最大元素 m int m = 0; foreach (int num in nums) { @@ -475,7 +475,7 @@ $$ ```csharp title="counting_sort.cs" /* 计数排序 */ // 完整实现,可排序对象,并且是稳定排序 - void countingSort(int[] nums) { + void CountingSort(int[] nums) { // 1. 统计数组最大元素 m int m = 0; foreach (int num in nums) { diff --git a/zh/chapter_sorting/heap_sort.md b/zh/chapter_sorting/heap_sort.md index 799ac9ea1..32b9d5735 100644 --- a/zh/chapter_sorting/heap_sort.md +++ b/zh/chapter_sorting/heap_sort.md @@ -192,7 +192,7 @@ comments: true ```csharp title="heap_sort.cs" /* 堆的长度为 n ,从节点 i 开始,从顶至底堆化 */ - void siftDown(int[] nums, int n, int i) { + void SiftDown(int[] nums, int n, int i) { while (true) { // 判断节点 i, l, r 中值最大的节点,记为 ma int l = 2 * i + 1; @@ -213,17 +213,17 @@ comments: true } /* 堆排序 */ - void heapSort(int[] nums) { + void HeapSort(int[] nums) { // 建堆操作:堆化除叶节点以外的其他所有节点 for (int i = nums.Length / 2 - 1; i >= 0; i--) { - siftDown(nums, nums.Length, i); + SiftDown(nums, nums.Length, i); } // 从堆中提取最大元素,循环 n-1 轮 for (int i = nums.Length - 1; i > 0; i--) { // 交换根节点与最右叶节点(即交换首元素与尾元素) (nums[i], nums[0]) = (nums[0], nums[i]); // 以根节点为起点,从顶至底进行堆化 - siftDown(nums, i, 0); + SiftDown(nums, i, 0); } } ``` diff --git a/zh/chapter_sorting/insertion_sort.md b/zh/chapter_sorting/insertion_sort.md index 27e483ccb..d4a22812c 100755 --- a/zh/chapter_sorting/insertion_sort.md +++ b/zh/chapter_sorting/insertion_sort.md @@ -83,7 +83,7 @@ comments: true ```csharp title="insertion_sort.cs" /* 插入排序 */ - void insertionSort(int[] nums) { + void InsertionSort(int[] nums) { // 外循环:已排序元素数量为 1, 2, ..., n for (int i = 1; i < nums.Length; i++) { int bas = nums[i], j = i - 1; diff --git a/zh/chapter_sorting/merge_sort.md b/zh/chapter_sorting/merge_sort.md index 9e2289c41..36f3e8d78 100755 --- a/zh/chapter_sorting/merge_sort.md +++ b/zh/chapter_sorting/merge_sort.md @@ -197,7 +197,7 @@ comments: true /* 合并左子数组和右子数组 */ // 左子数组区间 [left, mid] // 右子数组区间 [mid + 1, right] - void merge(int[] nums, int left, int mid, int right) { + void Merge(int[] nums, int left, int mid, int right) { // 初始化辅助数组 int[] tmp = nums[left..(right + 1)]; // 左子数组的起始索引和结束索引 @@ -221,15 +221,15 @@ comments: true } /* 归并排序 */ - void mergeSort(int[] nums, int left, int right) { + void MergeSort(int[] nums, int left, int right) { // 终止条件 if (left >= right) return; // 当子数组长度为 1 时终止递归 // 划分阶段 int mid = (left + right) / 2; // 计算中点 - mergeSort(nums, left, mid); // 递归左子数组 - mergeSort(nums, mid + 1, right); // 递归右子数组 + MergeSort(nums, left, mid); // 递归左子数组 + MergeSort(nums, mid + 1, right); // 递归右子数组 // 合并阶段 - merge(nums, left, mid, right); + Merge(nums, left, mid, right); } ``` diff --git a/zh/chapter_sorting/quick_sort.md b/zh/chapter_sorting/quick_sort.md index bd2c8256b..bd5c9bd26 100755 --- a/zh/chapter_sorting/quick_sort.md +++ b/zh/chapter_sorting/quick_sort.md @@ -122,14 +122,12 @@ comments: true ```csharp title="quick_sort.cs" /* 元素交换 */ - void swap(int[] nums, int i, int j) { - int tmp = nums[i]; - nums[i] = nums[j]; - nums[j] = tmp; + void Swap(int[] nums, int i, int j) { + (nums[j], nums[i]) = (nums[i], nums[j]); } /* 哨兵划分 */ - int partition(int[] nums, int left, int right) { + int Partition(int[] nums, int left, int right) { // 以 nums[left] 作为基准数 int i = left, j = right; while (i < j) { @@ -137,9 +135,9 @@ comments: true j--; // 从右向左找首个小于基准数的元素 while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素 - swap(nums, i, j); // 交换这两个元素 + Swap(nums, i, j); // 交换这两个元素 } - swap(nums, i, left); // 将基准数交换至两子数组的分界线 + Swap(nums, i, left); // 将基准数交换至两子数组的分界线 return i; // 返回基准数的索引 } ``` @@ -423,15 +421,15 @@ comments: true ```csharp title="quick_sort.cs" /* 快速排序 */ - void quickSort(int[] nums, int left, int right) { + void QuickSort(int[] nums, int left, int right) { // 子数组长度为 1 时终止递归 if (left >= right) return; // 哨兵划分 - int pivot = partition(nums, left, right); + int pivot = Partition(nums, left, right); // 递归左子数组、右子数组 - quickSort(nums, left, pivot - 1); - quickSort(nums, pivot + 1, right); + QuickSort(nums, left, pivot - 1); + QuickSort(nums, pivot + 1, right); } ``` @@ -719,7 +717,7 @@ comments: true ```csharp title="quick_sort.cs" /* 选取三个元素的中位数 */ - int medianThree(int[] nums, int left, int mid, int right) { + int MedianThree(int[] nums, int left, int mid, int right) { // 此处使用异或运算来简化代码 // 异或规则为 0 ^ 0 = 1 ^ 1 = 0, 0 ^ 1 = 1 ^ 0 = 1 if ((nums[left] < nums[mid]) ^ (nums[left] < nums[right])) @@ -731,11 +729,11 @@ comments: true } /* 哨兵划分(三数取中值) */ - int partition(int[] nums, int left, int right) { + int Partition(int[] nums, int left, int right) { // 选取三个候选元素的中位数 - int med = medianThree(nums, left, (left + right) / 2, right); + int med = MedianThree(nums, left, (left + right) / 2, right); // 将中位数交换至数组最左端 - swap(nums, left, med); + Swap(nums, left, med); // 以 nums[left] 作为基准数 int i = left, j = right; while (i < j) { @@ -743,9 +741,9 @@ comments: true j--; // 从右向左找首个小于基准数的元素 while (i < j && nums[i] <= nums[left]) i++; // 从左向右找首个大于基准数的元素 - swap(nums, i, j); // 交换这两个元素 + Swap(nums, i, j); // 交换这两个元素 } - swap(nums, i, left); // 将基准数交换至两子数组的分界线 + Swap(nums, i, left); // 将基准数交换至两子数组的分界线 return i; // 返回基准数的索引 } ``` @@ -1125,17 +1123,17 @@ comments: true ```csharp title="quick_sort.cs" /* 快速排序(尾递归优化) */ - void quickSort(int[] nums, int left, int right) { + void QuickSort(int[] nums, int left, int right) { // 子数组长度为 1 时终止 while (left < right) { // 哨兵划分操作 - int pivot = partition(nums, left, right); + int pivot = Partition(nums, left, right); // 对两个子数组中较短的那个执行快排 if (pivot - left < right - pivot) { - quickSort(nums, left, pivot - 1); // 递归排序左子数组 + QuickSort(nums, left, pivot - 1); // 递归排序左子数组 left = pivot + 1; // 剩余未排序区间为 [pivot + 1, right] } else { - quickSort(nums, pivot + 1, right); // 递归排序右子数组 + QuickSort(nums, pivot + 1, right); // 递归排序右子数组 right = pivot - 1; // 剩余未排序区间为 [left, pivot - 1] } } diff --git a/zh/chapter_sorting/radix_sort.md b/zh/chapter_sorting/radix_sort.md index cbb642444..2890bf086 100644 --- a/zh/chapter_sorting/radix_sort.md +++ b/zh/chapter_sorting/radix_sort.md @@ -183,19 +183,19 @@ $$ ```csharp title="radix_sort.cs" /* 获取元素 num 的第 k 位,其中 exp = 10^(k-1) */ - int digit(int num, int exp) { + int Digit(int num, int exp) { // 传入 exp 而非 k 可以避免在此重复执行昂贵的次方计算 return (num / exp) % 10; } /* 计数排序(根据 nums 第 k 位排序) */ - void countingSortDigit(int[] nums, int exp) { + void CountingSortDigit(int[] nums, int exp) { // 十进制的位范围为 0~9 ,因此需要长度为 10 的桶 int[] counter = new int[10]; int n = nums.Length; // 统计 0~9 各数字的出现次数 for (int i = 0; i < n; i++) { - int d = digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d + int d = Digit(nums[i], exp); // 获取 nums[i] 第 k 位,记为 d counter[d]++; // 统计数字 d 的出现次数 } // 求前缀和,将“出现个数”转换为“数组索引” @@ -205,7 +205,7 @@ $$ // 倒序遍历,根据桶内统计结果,将各元素填入 res int[] res = new int[n]; for (int i = n - 1; i >= 0; i--) { - int d = digit(nums[i], exp); + int d = Digit(nums[i], exp); int j = counter[d] - 1; // 获取 d 在数组中的索引 j res[j] = nums[i]; // 将当前元素填入索引 j counter[d]--; // 将 d 的数量减 1 @@ -217,7 +217,7 @@ $$ } /* 基数排序 */ - void radixSort(int[] nums) { + void RadixSort(int[] nums) { // 获取数组的最大元素,用于判断最大位数 int m = int.MinValue; foreach (int num in nums) { @@ -229,7 +229,7 @@ $$ // k = 1 -> exp = 1 // k = 2 -> exp = 10 // 即 exp = 10^(k-1) - countingSortDigit(nums, exp); + CountingSortDigit(nums, exp); } } ``` diff --git a/zh/chapter_sorting/selection_sort.md b/zh/chapter_sorting/selection_sort.md index a0817e8df..7eab27707 100644 --- a/zh/chapter_sorting/selection_sort.md +++ b/zh/chapter_sorting/selection_sort.md @@ -114,7 +114,7 @@ comments: true ```csharp title="selection_sort.cs" /* 选择排序 */ - void selectionSort(int[] nums) { + void SelectionSort(int[] nums) { int n = nums.Length; // 外循环:未排序区间为 [i, n-1] for (int i = 0; i < n - 1; i++) { diff --git a/zh/chapter_stack_and_queue/deque.md b/zh/chapter_stack_and_queue/deque.md index 740611222..ded13907f 100644 --- a/zh/chapter_stack_and_queue/deque.md +++ b/zh/chapter_stack_and_queue/deque.md @@ -120,7 +120,7 @@ comments: true ```csharp title="deque.cs" /* 初始化双向队列 */ // 在 C# 中,将链表 LinkedList 看作双向队列来使用 - LinkedList deque = new LinkedList(); + LinkedList deque = new(); /* 元素入队 */ deque.AddLast(2); // 添加至队尾 @@ -800,20 +800,20 @@ comments: true } /* 获取双向队列的长度 */ - public int size() { + public int Size() { return queSize; } /* 判断双向队列是否为空 */ - public bool isEmpty() { - return size() == 0; + public bool IsEmpty() { + return Size() == 0; } /* 入队操作 */ - private void push(int num, bool isFront) { - ListNode node = new ListNode(num); + private void Push(int num, bool isFront) { + ListNode node = new(num); // 若链表为空,则令 front, rear 都指向 node - if (isEmpty()) { + if (IsEmpty()) { front = node; rear = node; } @@ -836,25 +836,25 @@ comments: true } /* 队首入队 */ - public void pushFirst(int num) { - push(num, true); + public void PushFirst(int num) { + Push(num, true); } /* 队尾入队 */ - public void pushLast(int num) { - push(num, false); + public void PushLast(int num) { + Push(num, false); } /* 出队操作 */ - private int? pop(bool isFront) { - if (isEmpty()) + private int? Pop(bool isFront) { + if (IsEmpty()) throw new Exception(); - int val; + int? val; // 队首出队操作 if (isFront) { - val = front.val; // 暂存头节点值 + val = front?.val; // 暂存头节点值 // 删除头节点 - ListNode fNext = front.next; + ListNode? fNext = front?.next; if (fNext != null) { fNext.prev = null; front.next = null; @@ -863,9 +863,9 @@ comments: true } // 队尾出队操作 else { - val = rear.val; // 暂存尾节点值 + val = rear?.val; // 暂存尾节点值 // 删除尾节点 - ListNode rPrev = rear.prev; + ListNode? rPrev = rear?.prev; if (rPrev != null) { rPrev.next = null; rear.prev = null; @@ -878,36 +878,36 @@ comments: true } /* 队首出队 */ - public int? popFirst() { - return pop(true); + public int? PopFirst() { + return Pop(true); } /* 队尾出队 */ - public int? popLast() { - return pop(false); + public int? PopLast() { + return Pop(false); } /* 访问队首元素 */ - public int? peekFirst() { - if (isEmpty()) + public int? PeekFirst() { + if (IsEmpty()) throw new Exception(); - return front.val; + return front?.val; } /* 访问队尾元素 */ - public int? peekLast() { - if (isEmpty()) + public int? PeekLast() { + if (IsEmpty()) throw new Exception(); - return rear.val; + return rear?.val; } /* 返回数组用于打印 */ - public int[] toArray() { - ListNode node = front; - int[] res = new int[size()]; + public int?[] ToArray() { + ListNode? node = front; + int?[] res = new int?[Size()]; for (int i = 0; i < res.Length; i++) { - res[i] = node.val; - node = node.next; + res[i] = node?.val; + node = node?.next; } return res; @@ -2357,95 +2357,95 @@ comments: true } /* 获取双向队列的容量 */ - public int capacity() { + public int Capacity() { return nums.Length; } /* 获取双向队列的长度 */ - public int size() { + public int Size() { return queSize; } /* 判断双向队列是否为空 */ - public bool isEmpty() { + public bool IsEmpty() { return queSize == 0; } /* 计算环形数组索引 */ - private int index(int i) { + private int Index(int i) { // 通过取余操作实现数组首尾相连 // 当 i 越过数组尾部后,回到头部 // 当 i 越过数组头部后,回到尾部 - return (i + capacity()) % capacity(); + return (i + Capacity()) % Capacity(); } /* 队首入队 */ - public void pushFirst(int num) { - if (queSize == capacity()) { + public void PushFirst(int num) { + if (queSize == Capacity()) { Console.WriteLine("双向队列已满"); return; } // 队首指针向左移动一位 // 通过取余操作,实现 front 越过数组头部后回到尾部 - front = index(front - 1); + front = Index(front - 1); // 将 num 添加至队首 nums[front] = num; queSize++; } /* 队尾入队 */ - public void pushLast(int num) { - if (queSize == capacity()) { + public void PushLast(int num) { + if (queSize == Capacity()) { Console.WriteLine("双向队列已满"); return; } // 计算尾指针,指向队尾索引 + 1 - int rear = index(front + queSize); + int rear = Index(front + queSize); // 将 num 添加至队尾 nums[rear] = num; queSize++; } /* 队首出队 */ - public int popFirst() { - int num = peekFirst(); + public int PopFirst() { + int num = PeekFirst(); // 队首指针向后移动一位 - front = index(front + 1); + front = Index(front + 1); queSize--; return num; } /* 队尾出队 */ - public int popLast() { - int num = peekLast(); + public int PopLast() { + int num = PeekLast(); queSize--; return num; } /* 访问队首元素 */ - public int peekFirst() { - if (isEmpty()) { + public int PeekFirst() { + if (IsEmpty()) { throw new InvalidOperationException(); } return nums[front]; } /* 访问队尾元素 */ - public int peekLast() { - if (isEmpty()) { + public int PeekLast() { + if (IsEmpty()) { throw new InvalidOperationException(); } // 计算尾元素索引 - int last = index(front + queSize - 1); + int last = Index(front + queSize - 1); return nums[last]; } /* 返回数组用于打印 */ - public int[] toArray() { + public int[] ToArray() { // 仅转换有效长度范围内的列表元素 int[] res = new int[queSize]; for (int i = 0, j = front; i < queSize; i++, j++) { - res[i] = nums[index(j)]; + res[i] = nums[Index(j)]; } return res; } diff --git a/zh/chapter_stack_and_queue/queue.md b/zh/chapter_stack_and_queue/queue.md index d638cf9e0..0350fd066 100755 --- a/zh/chapter_stack_and_queue/queue.md +++ b/zh/chapter_stack_and_queue/queue.md @@ -556,19 +556,19 @@ comments: true } /* 获取队列的长度 */ - public int size() { + public int Size() { return queSize; } /* 判断队列是否为空 */ - public bool isEmpty() { - return size() == 0; + public bool IsEmpty() { + return Size() == 0; } /* 入队 */ - public void push(int num) { + public void Push(int num) { // 尾节点后添加 num - ListNode node = new ListNode(num); + ListNode node = new(num); // 如果队列为空,则令头、尾节点都指向该节点 if (front == null) { front = node; @@ -582,8 +582,8 @@ comments: true } /* 出队 */ - public int pop() { - int num = peek(); + public int Pop() { + int num = Peek(); // 删除头节点 front = front?.next; queSize--; @@ -591,19 +591,19 @@ comments: true } /* 访问队首元素 */ - public int peek() { - if (isEmpty()) + public int Peek() { + if (IsEmpty()) throw new Exception(); return front.val; } /* 将链表转化为 Array 并返回 */ - public int[] toArray() { + public int[] ToArray() { if (front == null) return Array.Empty(); ListNode node = front; - int[] res = new int[size()]; + int[] res = new int[Size()]; for (int i = 0; i < res.Length; i++) { res[i] = node.val; node = node.next; @@ -1446,7 +1446,7 @@ comments: true ```csharp title="array_queue.cs" /* 基于环形数组实现的队列 */ class ArrayQueue { - private int[] nums; // 用于存储队列元素的数组 + private readonly int[] nums; // 用于存储队列元素的数组 private int front; // 队首指针,指向队首元素 private int queSize; // 队列长度 @@ -1456,56 +1456,56 @@ comments: true } /* 获取队列的容量 */ - public int capacity() { + public int Capacity() { return nums.Length; } /* 获取队列的长度 */ - public int size() { + public int Size() { return queSize; } /* 判断队列是否为空 */ - public bool isEmpty() { + public bool IsEmpty() { return queSize == 0; } /* 入队 */ - public void push(int num) { - if (queSize == capacity()) { + public void Push(int num) { + if (queSize == Capacity()) { Console.WriteLine("队列已满"); return; } // 计算尾指针,指向队尾索引 + 1 // 通过取余操作,实现 rear 越过数组尾部后回到头部 - int rear = (front + queSize) % capacity(); + int rear = (front + queSize) % Capacity(); // 将 num 添加至队尾 nums[rear] = num; queSize++; } /* 出队 */ - public int pop() { - int num = peek(); + public int Pop() { + int num = Peek(); // 队首指针向后移动一位,若越过尾部则返回到数组头部 - front = (front + 1) % capacity(); + front = (front + 1) % Capacity(); queSize--; return num; } /* 访问队首元素 */ - public int peek() { - if (isEmpty()) + public int Peek() { + if (IsEmpty()) throw new Exception(); return nums[front]; } /* 返回数组 */ - public int[] toArray() { + public int[] ToArray() { // 仅转换有效长度范围内的列表元素 int[] res = new int[queSize]; for (int i = 0, j = front; i < queSize; i++, j++) { - res[i] = nums[j % this.capacity()]; + res[i] = nums[j % this.Capacity()]; } return res; } diff --git a/zh/chapter_stack_and_queue/stack.md b/zh/chapter_stack_and_queue/stack.md index 7261fed97..d43e17b8e 100755 --- a/zh/chapter_stack_and_queue/stack.md +++ b/zh/chapter_stack_and_queue/stack.md @@ -115,7 +115,7 @@ comments: true ```csharp title="stack.cs" /* 初始化栈 */ - Stack stack = new (); + Stack stack = new(); /* 元素入栈 */ stack.Push(1); @@ -526,45 +526,46 @@ comments: true } /* 获取栈的长度 */ - public int size() { + public int Size() { return stkSize; } /* 判断栈是否为空 */ - public bool isEmpty() { - return size() == 0; + public bool IsEmpty() { + return Size() == 0; } /* 入栈 */ - public void push(int num) { - ListNode node = new ListNode(num); - node.next = stackPeek; + public void Push(int num) { + ListNode node = new(num) { + next = stackPeek + }; stackPeek = node; stkSize++; } /* 出栈 */ - public int pop() { - int num = peek(); + public int Pop() { + int num = Peek(); stackPeek = stackPeek.next; stkSize--; return num; } /* 访问栈顶元素 */ - public int peek() { - if (isEmpty()) + public int Peek() { + if (IsEmpty()) throw new Exception(); return stackPeek.val; } /* 将 List 转化为 Array 并返回 */ - public int[] toArray() { + public int[] ToArray() { if (stackPeek == null) return Array.Empty(); ListNode node = stackPeek; - int[] res = new int[size()]; + int[] res = new int[Size()]; for (int i = res.Length - 1; i >= 0; i--) { res[i] = node.val; node = node.next; @@ -1238,45 +1239,45 @@ comments: true ```csharp title="array_stack.cs" /* 基于数组实现的栈 */ class ArrayStack { - private List stack; + private readonly List stack; public ArrayStack() { // 初始化列表(动态数组) stack = new(); } /* 获取栈的长度 */ - public int size() { - return stack.Count(); + public int Size() { + return stack.Count; } /* 判断栈是否为空 */ - public bool isEmpty() { - return size() == 0; + public bool IsEmpty() { + return Size() == 0; } /* 入栈 */ - public void push(int num) { + public void Push(int num) { stack.Add(num); } /* 出栈 */ - public int pop() { - if (isEmpty()) + public int Pop() { + if (IsEmpty()) throw new Exception(); - var val = peek(); - stack.RemoveAt(size() - 1); + var val = Peek(); + stack.RemoveAt(Size() - 1); return val; } /* 访问栈顶元素 */ - public int peek() { - if (isEmpty()) + public int Peek() { + if (IsEmpty()) throw new Exception(); - return stack[size() - 1]; + return stack[Size() - 1]; } /* 将 List 转化为 Array 并返回 */ - public int[] toArray() { + public int[] ToArray() { return stack.ToArray(); } } diff --git a/zh/chapter_tree/array_representation_of_tree.md b/zh/chapter_tree/array_representation_of_tree.md index a3252e68f..fbbc36728 100644 --- a/zh/chapter_tree/array_representation_of_tree.md +++ b/zh/chapter_tree/array_representation_of_tree.md @@ -411,7 +411,7 @@ comments: true ```csharp title="array_binary_tree.cs" /* 数组表示下的二叉树类 */ class ArrayBinaryTree { - private List tree; + private readonly List tree; /* 构造方法 */ public ArrayBinaryTree(List arr) { @@ -419,80 +419,80 @@ comments: true } /* 节点数量 */ - public int size() { + public int Size() { return tree.Count; } /* 获取索引为 i 节点的值 */ - public int? val(int i) { + public int? Val(int i) { // 若索引越界,则返回 null ,代表空位 - if (i < 0 || i >= size()) + if (i < 0 || i >= Size()) return null; return tree[i]; } /* 获取索引为 i 节点的左子节点的索引 */ - public int left(int i) { + public int Left(int i) { return 2 * i + 1; } /* 获取索引为 i 节点的右子节点的索引 */ - public int right(int i) { + public int Right(int i) { return 2 * i + 2; } /* 获取索引为 i 节点的父节点的索引 */ - public int parent(int i) { + public int Parent(int i) { return (i - 1) / 2; } /* 层序遍历 */ - public List levelOrder() { - List res = new List(); + public List LevelOrder() { + List res = new(); // 直接遍历数组 - for (int i = 0; i < size(); i++) { - if (val(i).HasValue) - res.Add(val(i).Value); + for (int i = 0; i < Size(); i++) { + if (Val(i).HasValue) + res.Add(Val(i).Value); } return res; } /* 深度优先遍历 */ - private void dfs(int i, string order, List res) { + private void Dfs(int i, string order, List res) { // 若为空位,则返回 - if (!val(i).HasValue) + if (!Val(i).HasValue) return; // 前序遍历 if (order == "pre") - res.Add(val(i).Value); - dfs(left(i), order, res); + res.Add(Val(i).Value); + Dfs(Left(i), order, res); // 中序遍历 if (order == "in") - res.Add(val(i).Value); - dfs(right(i), order, res); + res.Add(Val(i).Value); + Dfs(Right(i), order, res); // 后序遍历 if (order == "post") - res.Add(val(i).Value); + res.Add(Val(i).Value); } /* 前序遍历 */ - public List preOrder() { - List res = new List(); - dfs(0, "pre", res); + public List PreOrder() { + List res = new(); + Dfs(0, "pre", res); return res; } /* 中序遍历 */ - public List inOrder() { - List res = new List(); - dfs(0, "in", res); + public List InOrder() { + List res = new(); + Dfs(0, "in", res); return res; } /* 后序遍历 */ - public List postOrder() { - List res = new List(); - dfs(0, "post", res); + public List PostOrder() { + List res = new(); + Dfs(0, "post", res); return res; } } diff --git a/zh/chapter_tree/avl_tree.md b/zh/chapter_tree/avl_tree.md index 8ba5c3e13..9fcef472c 100644 --- a/zh/chapter_tree/avl_tree.md +++ b/zh/chapter_tree/avl_tree.md @@ -271,15 +271,15 @@ AVL 树既是二叉搜索树也是平衡二叉树,同时满足这两类二叉 ```csharp title="avl_tree.cs" /* 获取节点高度 */ - int height(TreeNode? node) { + int Height(TreeNode? node) { // 空节点高度为 -1 ,叶节点高度为 0 return node == null ? -1 : node.height; } /* 更新节点高度 */ - void updateHeight(TreeNode node) { + void UpdateHeight(TreeNode node) { // 节点高度等于最高子树高度 + 1 - node.height = Math.Max(height(node.left), height(node.right)) + 1; + node.height = Math.Max(Height(node.left), Height(node.right)) + 1; } ``` @@ -485,11 +485,11 @@ AVL 树既是二叉搜索树也是平衡二叉树,同时满足这两类二叉 ```csharp title="avl_tree.cs" /* 获取平衡因子 */ - int balanceFactor(TreeNode? node) { + int BalanceFactor(TreeNode? node) { // 空节点平衡因子为 0 if (node == null) return 0; // 节点平衡因子 = 左子树高度 - 右子树高度 - return height(node.left) - height(node.right); + return Height(node.left) - Height(node.right); } ``` @@ -690,15 +690,15 @@ AVL 树的特点在于“旋转”操作,它能够在不影响二叉树的中 ```csharp title="avl_tree.cs" /* 右旋操作 */ - TreeNode? rightRotate(TreeNode? node) { + TreeNode? RightRotate(TreeNode? node) { TreeNode? child = node.left; TreeNode? grandChild = child?.right; // 以 child 为原点,将 node 向右旋转 child.right = node; node.left = grandChild; // 更新节点高度 - updateHeight(node); - updateHeight(child); + UpdateHeight(node); + UpdateHeight(child); // 返回旋转后子树的根节点 return child; } @@ -927,15 +927,15 @@ AVL 树的特点在于“旋转”操作,它能够在不影响二叉树的中 ```csharp title="avl_tree.cs" /* 左旋操作 */ - TreeNode? leftRotate(TreeNode? node) { + TreeNode? LeftRotate(TreeNode? node) { TreeNode? child = node.right; TreeNode? grandChild = child?.left; // 以 child 为原点,将 node 向左旋转 child.left = node; node.right = grandChild; // 更新节点高度 - updateHeight(node); - updateHeight(child); + UpdateHeight(node); + UpdateHeight(child); // 返回旋转后子树的根节点 return child; } @@ -1233,29 +1233,29 @@ AVL 树的特点在于“旋转”操作,它能够在不影响二叉树的中 ```csharp title="avl_tree.cs" /* 执行旋转操作,使该子树重新恢复平衡 */ - TreeNode? rotate(TreeNode? node) { + TreeNode? Rotate(TreeNode? node) { // 获取节点 node 的平衡因子 - int balanceFactorInt = balanceFactor(node); + int balanceFactorInt = BalanceFactor(node); // 左偏树 if (balanceFactorInt > 1) { - if (balanceFactor(node.left) >= 0) { + if (BalanceFactor(node.left) >= 0) { // 右旋 - return rightRotate(node); + return RightRotate(node); } else { // 先左旋后右旋 - node.left = leftRotate(node?.left); - return rightRotate(node); + node.left = LeftRotate(node?.left); + return RightRotate(node); } } // 右偏树 if (balanceFactorInt < -1) { - if (balanceFactor(node.right) <= 0) { + if (BalanceFactor(node.right) <= 0) { // 左旋 - return leftRotate(node); + return LeftRotate(node); } else { // 先右旋后左旋 - node.right = rightRotate(node?.right); - return leftRotate(node); + node.right = RightRotate(node?.right); + return LeftRotate(node); } } // 平衡树,无须旋转,直接返回 @@ -1630,23 +1630,23 @@ AVL 树的节点插入操作与二叉搜索树在主体上类似。唯一的区 ```csharp title="avl_tree.cs" /* 插入节点 */ - void insert(int val) { - root = insertHelper(root, val); + void Insert(int val) { + root = InsertHelper(root, val); } /* 递归插入节点(辅助方法) */ - TreeNode? insertHelper(TreeNode? node, int val) { + TreeNode? InsertHelper(TreeNode? node, int val) { if (node == null) return new TreeNode(val); /* 1. 查找插入位置,并插入节点 */ if (val < node.val) - node.left = insertHelper(node.left, val); + node.left = InsertHelper(node.left, val); else if (val > node.val) - node.right = insertHelper(node.right, val); + node.right = InsertHelper(node.right, val); else return node; // 重复节点不插入,直接返回 - updateHeight(node); // 更新节点高度 + UpdateHeight(node); // 更新节点高度 /* 2. 执行旋转操作,使该子树重新恢复平衡 */ - node = rotate(node); + node = Rotate(node); // 返回子树的根节点 return node; } @@ -2034,21 +2034,21 @@ AVL 树的节点插入操作与二叉搜索树在主体上类似。唯一的区 ```csharp title="avl_tree.cs" /* 删除节点 */ - void remove(int val) { - root = removeHelper(root, val); + void Remove(int val) { + root = RemoveHelper(root, val); } /* 递归删除节点(辅助方法) */ - TreeNode? removeHelper(TreeNode? node, int val) { + TreeNode? RemoveHelper(TreeNode? node, int val) { if (node == null) return null; /* 1. 查找节点,并删除之 */ if (val < node.val) - node.left = removeHelper(node.left, val); + node.left = RemoveHelper(node.left, val); else if (val > node.val) - node.right = removeHelper(node.right, val); + node.right = RemoveHelper(node.right, val); else { if (node.left == null || node.right == null) { - TreeNode? child = node.left != null ? node.left : node.right; + TreeNode? child = node.left ?? node.right; // 子节点数量 = 0 ,直接删除 node 并返回 if (child == null) return null; @@ -2061,13 +2061,13 @@ AVL 树的节点插入操作与二叉搜索树在主体上类似。唯一的区 while (temp.left != null) { temp = temp.left; } - node.right = removeHelper(node.right, temp.val); + node.right = RemoveHelper(node.right, temp.val); node.val = temp.val; } } - updateHeight(node); // 更新节点高度 + UpdateHeight(node); // 更新节点高度 /* 2. 执行旋转操作,使该子树重新恢复平衡 */ - node = rotate(node); + node = Rotate(node); // 返回子树的根节点 return node; } diff --git a/zh/chapter_tree/binary_search_tree.md b/zh/chapter_tree/binary_search_tree.md index cb8343e6b..6107f1908 100755 --- a/zh/chapter_tree/binary_search_tree.md +++ b/zh/chapter_tree/binary_search_tree.md @@ -111,7 +111,7 @@ comments: true ```csharp title="binary_search_tree.cs" /* 查找节点 */ - TreeNode? search(int num) { + TreeNode? Search(int num) { TreeNode? cur = root; // 循环查找,越过叶节点后跳出 while (cur != null) { @@ -434,7 +434,7 @@ comments: true ```csharp title="binary_search_tree.cs" /* 插入节点 */ - void insert(int num) { + void Insert(int num) { // 若树为空,则初始化根节点 if (root == null) { root = new TreeNode(num); @@ -456,7 +456,7 @@ comments: true } // 插入节点 - TreeNode node = new TreeNode(num); + TreeNode node = new(num); if (pre != null) { if (pre.val < num) pre.right = node; @@ -953,7 +953,7 @@ comments: true ```csharp title="binary_search_tree.cs" /* 删除节点 */ - void remove(int num) { + void Remove(int num) { // 若树为空,直接提前返回 if (root == null) return; @@ -977,7 +977,7 @@ comments: true // 子节点数量 = 0 or 1 if (cur.left == null || cur.right == null) { // 当子节点数量 = 0 / 1 时, child = null / 该子节点 - TreeNode? child = cur.left != null ? cur.left : cur.right; + TreeNode? child = cur.left ?? cur.right; // 删除节点 cur if (cur != root) { if (pre.left == cur) @@ -997,7 +997,7 @@ comments: true tmp = tmp.left; } // 递归删除节点 tmp - remove(tmp.val); + Remove(tmp.val); // 用 tmp 覆盖 cur cur.val = tmp.val; } diff --git a/zh/chapter_tree/binary_tree.md b/zh/chapter_tree/binary_tree.md index 5bd5f8778..6eb0edfe3 100644 --- a/zh/chapter_tree/binary_tree.md +++ b/zh/chapter_tree/binary_tree.md @@ -279,11 +279,11 @@ comments: true ```csharp title="binary_tree.cs" /* 初始化二叉树 */ // 初始化节点 - TreeNode n1 = new TreeNode(1); - TreeNode n2 = new TreeNode(2); - TreeNode n3 = new TreeNode(3); - TreeNode n4 = new TreeNode(4); - TreeNode n5 = new TreeNode(5); + TreeNode n1 = new(1); + TreeNode n2 = new(2); + TreeNode n3 = new(3); + TreeNode n4 = new(4); + TreeNode n5 = new(5); // 构建引用指向(即指针) n1.left = n2; n1.right = n3; @@ -461,7 +461,7 @@ comments: true ```csharp title="binary_tree.cs" /* 插入与删除节点 */ - TreeNode P = new TreeNode(0); + TreeNode P = new(0); // 在 n1 -> n2 中间插入节点 P n1.left = P; P.left = n2; diff --git a/zh/chapter_tree/binary_tree_traversal.md b/zh/chapter_tree/binary_tree_traversal.md index aa93bffc1..c6a6fd1ca 100755 --- a/zh/chapter_tree/binary_tree_traversal.md +++ b/zh/chapter_tree/binary_tree_traversal.md @@ -91,7 +91,7 @@ comments: true ```csharp title="binary_tree_bfs.cs" /* 层序遍历 */ - List levelOrder(TreeNode root) { + List LevelOrder(TreeNode root) { // 初始化队列,加入根节点 Queue queue = new(); queue.Enqueue(root); @@ -446,29 +446,29 @@ comments: true ```csharp title="binary_tree_dfs.cs" /* 前序遍历 */ - void preOrder(TreeNode? root) { + void PreOrder(TreeNode? root) { if (root == null) return; // 访问优先级:根节点 -> 左子树 -> 右子树 list.Add(root.val); - preOrder(root.left); - preOrder(root.right); + PreOrder(root.left); + PreOrder(root.right); } /* 中序遍历 */ - void inOrder(TreeNode? root) { + void InOrder(TreeNode? root) { if (root == null) return; // 访问优先级:左子树 -> 根节点 -> 右子树 - inOrder(root.left); + InOrder(root.left); list.Add(root.val); - inOrder(root.right); + InOrder(root.right); } /* 后序遍历 */ - void postOrder(TreeNode? root) { + void PostOrder(TreeNode? root) { if (root == null) return; // 访问优先级:左子树 -> 右子树 -> 根节点 - postOrder(root.left); - postOrder(root.right); + PostOrder(root.left); + PostOrder(root.right); list.Add(root.val); } ```