From 53a75deff46aba3fc2612a843852da9acc79172a Mon Sep 17 00:00:00 2001 From: krahets Date: Mon, 3 Jul 2023 16:55:36 +0800 Subject: [PATCH] build --- .../dp_problem_features.md | 51 +++++++++- .../intro_to_dynamic_programming.md | 92 +++++++++++++++++-- chapter_hashing/hash_algorithm.md | 70 +++++++++++++- index.md | 1 + 4 files changed, 199 insertions(+), 15 deletions(-) diff --git a/chapter_dynamic_programming/dp_problem_features.md b/chapter_dynamic_programming/dp_problem_features.md index 6e0d98d32..5f6b4f825 100644 --- a/chapter_dynamic_programming/dp_problem_features.md +++ b/chapter_dynamic_programming/dp_problem_features.md @@ -123,7 +123,22 @@ $$ === "C#" ```csharp title="min_cost_climbing_stairs_dp.cs" - [class]{min_cost_climbing_stairs_dp}-[func]{minCostClimbingStairsDP} + /* 爬楼梯最小代价:动态规划 */ + int minCostClimbingStairsDP(int[] cost) { + int n = cost.Length - 1; + if (n == 1 || n == 2) + return cost[n]; + // 初始化 dp 列表,用于存储子问题的解 + int[] dp = new int[n + 1]; + // 初始状态:预设最小子问题的解 + dp[1] = cost[1]; + dp[2] = cost[2]; + // 状态转移:从较小子问题逐步求解较大子问题 + for (int i = 3; i <= n; i++) { + dp[i] = Math.Min(dp[i - 1], dp[i - 2]) + cost[i]; + } + return dp[n]; + } ``` === "Swift" @@ -227,7 +242,19 @@ $$ === "C#" ```csharp title="min_cost_climbing_stairs_dp.cs" - [class]{min_cost_climbing_stairs_dp}-[func]{minCostClimbingStairsDPComp} + /* 爬楼梯最小代价:状态压缩后的动态规划 */ + int minCostClimbingStairsDPComp(int[] cost) { + int n = cost.Length - 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 = Math.Min(a, tmp) + cost[i]; + a = tmp; + } + return b; + } ``` === "Swift" @@ -384,7 +411,25 @@ $$ === "C#" ```csharp title="climbing_stairs_constraint_dp.cs" - [class]{climbing_stairs_constraint_dp}-[func]{climbingStairsConstraintDP} + /* 带约束爬楼梯:动态规划 */ + int climbingStairsConstraintDP(int n) { + if (n == 1 || n == 2) { + return n; + } + // 初始化 dp 列表,用于存储子问题的解 + int[,] dp = new int[n + 1, 3]; + // 初始状态:预设最小子问题的解 + dp[1, 1] = 1; + dp[1, 2] = 0; + dp[2, 1] = 0; + dp[2, 2] = 1; + // 状态转移:从较小子问题逐步求解较大子问题 + for (int i = 3; i <= n; i++) { + dp[i, 1] = dp[i - 1, 2]; + dp[i, 2] = dp[i - 2, 1] + dp[i - 2, 2]; + } + return dp[n, 1] + dp[n, 2]; + } ``` === "Swift" diff --git a/chapter_dynamic_programming/intro_to_dynamic_programming.md b/chapter_dynamic_programming/intro_to_dynamic_programming.md index fd285a873..a32b5fb1e 100644 --- a/chapter_dynamic_programming/intro_to_dynamic_programming.md +++ b/chapter_dynamic_programming/intro_to_dynamic_programming.md @@ -140,9 +140,30 @@ comments: true === "C#" ```csharp title="climbing_stairs_backtrack.cs" - [class]{climbing_stairs_backtrack}-[func]{backtrack} + /* 回溯 */ + void backtrack(List choices, int state, int n, List res) { + // 当爬到第 n 阶时,方案数量加 1 + if (state == n) + res[0]++; + // 遍历所有选择 + foreach (int choice in choices) { + // 剪枝:不允许越过第 n 阶 + if (state + choice > n) + break; + // 尝试:做出选择,更新状态 + backtrack(choices, state + choice, n, res); + // 回退 + } + } - [class]{climbing_stairs_backtrack}-[func]{climbingStairsBacktrack} + /* 爬楼梯:回溯 */ + int climbingStairsBacktrack(int n) { + List choices = new List { 1, 2 }; // 可选择向上爬 1 或 2 阶 + int state = 0; // 从第 0 阶开始爬 + List res = new List { 0 }; // 使用 res[0] 记录方案数量 + backtrack(choices, state, n, res); + return res[0]; + } ``` === "Swift" @@ -285,9 +306,20 @@ $$ === "C#" ```csharp title="climbing_stairs_dfs.cs" - [class]{climbing_stairs_dfs}-[func]{dfs} + /* 搜索 */ + 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); + return count; + } - [class]{climbing_stairs_dfs}-[func]{climbingStairsDFS} + /* 爬楼梯:搜索 */ + int climbingStairsDFS(int n) { + return dfs(n); + } ``` === "Swift" @@ -441,9 +473,28 @@ $$ === "C#" ```csharp title="climbing_stairs_dfs_mem.cs" - [class]{climbing_stairs_dfs_mem}-[func]{dfs} + /* 记忆化搜索 */ + int dfs(int i, int[] mem) { + // 已知 dp[1] 和 dp[2] ,返回之 + if (i == 1 || i == 2) + return i; + // 若存在记录 dp[i] ,则直接返回之 + 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); + // 记录 dp[i] + mem[i] = count; + return count; + } - [class]{climbing_stairs_dfs_mem}-[func]{climbingStairsDFSMem} + /* 爬楼梯:记忆化搜索 */ + int climbingStairsDFSMem(int n) { + // mem[i] 记录爬到第 i 阶的方案总数,-1 代表无记录 + int[] mem = new int[n + 1]; + Array.Fill(mem, -1); + return dfs(n, mem); + } ``` === "Swift" @@ -568,7 +619,21 @@ $$ === "C#" ```csharp title="climbing_stairs_dp.cs" - [class]{climbing_stairs_dp}-[func]{climbingStairsDP} + /* 爬楼梯:动态规划 */ + int climbingStairsDP(int n) { + if (n == 1 || n == 2) + return n; + // 初始化 dp 列表,用于存储子问题的解 + int[] dp = new int[n + 1]; + // 初始状态:预设最小子问题的解 + dp[1] = 1; + dp[2] = 2; + // 状态转移:从较小子问题逐步求解较大子问题 + for (int i = 3; i <= n; i++) { + dp[i] = dp[i - 1] + dp[i - 2]; + } + return dp[n]; + } ``` === "Swift" @@ -675,7 +740,18 @@ $$ === "C#" ```csharp title="climbing_stairs_dp.cs" - [class]{climbing_stairs_dp}-[func]{climbingStairsDPComp} + /* 爬楼梯:状态压缩后的动态规划 */ + int climbingStairsDPComp(int n) { + if (n == 1 || n == 2) + return n; + int a = 1, b = 2; + for (int i = 3; i <= n; i++) { + int tmp = b; + b = a + b; + a = tmp; + } + return b; + } ``` === "Swift" diff --git a/chapter_hashing/hash_algorithm.md b/chapter_hashing/hash_algorithm.md index eb20cbd0c..f1e946bee 100644 --- a/chapter_hashing/hash_algorithm.md +++ b/chapter_hashing/hash_algorithm.md @@ -309,13 +309,53 @@ index = hash(key) % capacity === "Swift" ```swift title="simple_hash.swift" - [class]{}-[func]{addHash} + /* 加法哈希 */ + func addHash(key: String) -> Int { + var hash = 0 + let MODULUS = 1_000_000_007 + for c in key { + for scalar in c.unicodeScalars { + hash = (hash + Int(scalar.value)) % MODULUS + } + } + return hash + } - [class]{}-[func]{mulHash} + /* 乘法哈希 */ + func mulHash(key: String) -> Int { + var hash = 0 + let MODULUS = 1_000_000_007 + for c in key { + for scalar in c.unicodeScalars { + hash = (31 * hash + Int(scalar.value)) % MODULUS + } + } + return hash + } - [class]{}-[func]{xorHash} + /* 异或哈希 */ + func xorHash(key: String) -> Int { + var hash = 0 + let MODULUS = 1_000_000_007 + for c in key { + for scalar in c.unicodeScalars { + hash ^= Int(scalar.value) + } + } + return hash & MODULUS + } - [class]{}-[func]{rotHash} + /* 旋转哈希 */ + func rotHash(key: String) -> Int { + var hash = 0 + let MODULUS = 1_000_000_007 + for c in key { + for scalar in c.unicodeScalars { + hash = ((hash << 4) ^ (hash >> 28) ^ Int(scalar.value)) % MODULUS + } + } + return hash + } ``` === "Zig" @@ -533,7 +573,29 @@ $$ === "Swift" ```swift title="built_in_hash.swift" + let num = 3 + let hashNum = num.hashValue + // 整数 3 的哈希值为 9047044699613009734 + let bol = true + let hashBol = bol.hashValue + // 布尔量 true 的哈希值为 -4431640247352757451 + + let dec = 3.14159 + let hashDec = dec.hashValue + // 小数 3.14159 的哈希值为 -2465384235396674631 + + let str = "Hello 算法" + let hashStr = str.hashValue + // 字符串 Hello 算法 的哈希值为 -7850626797806988787 + + let arr = [AnyHashable(12836), AnyHashable("小哈")] + let hashTup = arr.hashValue + // 数组 [AnyHashable(12836), AnyHashable("小哈")] 的哈希值为 -2308633508154532996 + + let obj = ListNode(x: 0) + let hashObj = obj.hashValue + // 节点对象 utils.ListNode 的哈希值为 -2434780518035996159 ``` === "Zig" diff --git a/index.md b/index.md index 9d2e99f57..aef9799c6 100644 --- a/index.md +++ b/index.md @@ -113,6 +113,7 @@ hide: Gonglja
Gonglja

C / C++ gvenusleo
gvenusleo

Dart + hpstory
hpstory

C# justin-tse
justin-tse

JS / TS krahets
krahets

Java / Python nuomi1
nuomi1

Swift