add python code

This commit is contained in:
2026-06-16 09:35:51 +08:00
parent daecbf4603
commit daf9e50938
17 changed files with 763 additions and 19 deletions
+32
View File
@@ -0,0 +1,32 @@
"""
性能对比:循环累加 vs 高斯求和公式
比较两种算法计算 1+2+...+n 的耗时差异
"""
import time
def sum_by_loop(n):
"""循环累加 O(n)"""
total = 0
for i in range(1, n + 1):
total += i
return total
def sum_by_gauss(n):
"""高斯求和公式 O(1)"""
return n * (n + 1) // 2
# 测试不同规模
for n in [1000, 10000, 100000, 1000000]:
print(f"\n--- n = {n} ---")
start = time.time()
r1 = sum_by_loop(n)
t1 = time.time() - start
start = time.time()
r2 = sum_by_gauss(n)
t2 = time.time() - start
print(f"循环累加: {t1:.6f} 秒, 结果 = {r1}")
print(f"高斯公式: {t2:.6f} 秒, 结果 = {r2}")
print(f"加速比: {t1/t2:.2f}x")
+22
View File
@@ -0,0 +1,22 @@
"""
递归打印图案 — 演示递归基本结构
"""
def print_rect(n, current=1):
"""递归打印矩形"""
if current > n:
return
print("*" * n)
print_rect(n, current + 1)
def print_triangle(n, current=1):
"""递归打印三角形"""
if current > n:
return
print("*" * current)
print_triangle(n, current + 1)
if __name__ == "__main__":
print("矩形图案 (5x5):")
print_rect(5)
print("\n三角形图案:")
print_triangle(5)
+34
View File
@@ -0,0 +1,34 @@
"""
全排列生成 — 递归交换法
生成 n 个元素的所有排列 (n!)
"""
def permute(arr, start, end):
"""递归生成全排列"""
if start == end:
print("".join(map(str, arr)))
else:
for i in range(start, end + 1):
arr[start], arr[i] = arr[i], arr[start]
permute(arr, start + 1, end)
arr[start], arr[i] = arr[i], arr[start] # 回溯
def permute_unique(arr, start, end):
"""生成去重全排列"""
if start == end:
print("".join(map(str, arr)))
else:
seen = set()
for i in range(start, end + 1):
if arr[i] not in seen:
seen.add(arr[i])
arr[start], arr[i] = arr[i], arr[start]
permute_unique(arr, start + 1, end)
arr[start], arr[i] = arr[i], arr[start]
if __name__ == "__main__":
print("全排列 [1,2,3]:")
permute([1, 2, 3], 0, 2)
print("\n去重全排列 [1,1,2]:")
permute_unique([1, 1, 2], 0, 2)
+25
View File
@@ -0,0 +1,25 @@
"""
递归示例 — 递归打印整数各位数字
"""
def print_digits(n):
"""递归按位打印整数(高位到低位)"""
if n < 10:
print(n, end=" ")
else:
print_digits(n // 10)
print(n % 10, end=" ")
def print_triangle(n, current=1):
"""递归打印星号三角形"""
if current > n:
return
print("*" * current)
print_triangle(n, current + 1)
if __name__ == "__main__":
n = 12345
print(f"递归打印 {n} 的各位数字:")
print_digits(n)
print("\n\n递归三角形 (n=5):")
print_triangle(5)
+43
View File
@@ -0,0 +1,43 @@
"""
二分查找 — 在有序数组中查找目标值
时间复杂度 O(log n)
"""
def binary_search_recursive(arr, target, left, right):
"""递归版二分查找"""
if left > right:
return -1
mid = left + (right - left) // 2
if arr[mid] == target:
return mid
elif arr[mid] > target:
return binary_search_recursive(arr, target, left, mid - 1)
else:
return binary_search_recursive(arr, target, mid + 1, right)
def binary_search_iterative(arr, target):
"""迭代版二分查找"""
left, right = 0, len(arr) - 1
while left <= right:
mid = left + (right - left) // 2
if arr[mid] == target:
return mid
elif arr[mid] > target:
right = mid - 1
else:
left = mid + 1
return -1
if __name__ == "__main__":
arr = [1, 3, 5, 7, 9, 11, 13, 15]
target = 7
idx1 = binary_search_recursive(arr, target, 0, len(arr) - 1)
idx2 = binary_search_iterative(arr, target)
print(f"数组: {arr}")
print(f"查找 {target}: 递归版结果索引={idx1}, 迭代版结果索引={idx2}")
+50
View File
@@ -0,0 +1,50 @@
"""
归并排序 — 分治法的经典应用
时间复杂度 O(n log n),空间复杂度 O(n)
"""
def merge(arr, left, mid, right):
"""合并两个有序子数组"""
# 创建临时数组
L = arr[left:mid + 1]
R = arr[mid + 1:right + 1]
i = j = 0
k = left
# 合并两个有序数组
while i < len(L) and j < len(R):
if L[i] <= R[j]:
arr[k] = L[i]
i += 1
else:
arr[k] = R[j]
j += 1
k += 1
# 复制剩余元素
while i < len(L):
arr[k] = L[i]
i += 1
k += 1
while j < len(R):
arr[k] = R[j]
j += 1
k += 1
def merge_sort(arr, left, right):
"""归并排序主函数"""
if left < right:
mid = (left + right) // 2
merge_sort(arr, left, mid)
merge_sort(arr, mid + 1, right)
merge(arr, left, mid, right)
def sort(arr):
merge_sort(arr, 0, len(arr) - 1)
if __name__ == "__main__":
data = [38, 27, 43, 3, 9, 82, 10]
print("排序前:", data)
sort(data)
print("排序后:", data)
+33
View File
@@ -0,0 +1,33 @@
"""
快速排序 — 分治策略
平均时间复杂度 O(n log n),最坏 O(n²)
"""
def partition(arr, low, high):
"""划分:选择基准,将小于基准的放左边,大于的放右边"""
pivot = arr[high] # 选最后一个元素作为基准
i = low - 1
for j in range(low, high):
if arr[j] <= pivot:
i += 1
arr[i], arr[j] = arr[j], arr[i]
arr[i + 1], arr[high] = arr[high], arr[i + 1]
return i + 1
def quick_sort(arr, low, high):
"""快速排序递归实现"""
if low < high:
pi = partition(arr, low, high)
quick_sort(arr, low, pi - 1)
quick_sort(arr, pi + 1, high)
def sort(arr):
quick_sort(arr, 0, len(arr) - 1)
if __name__ == "__main__":
data = [10, 7, 8, 9, 1, 5]
print("排序前:", data)
sort(data)
print("排序后:", data)
+47
View File
@@ -0,0 +1,47 @@
"""
0/1 背包问题 — 动态规划经典问题
给定容量 W 和价值/重量数组,求最大价值
"""
def knapsack_01(weights, values, W):
"""0/1背包 DP 解法"""
n = len(weights)
# dp[i][w] 表示前 i 个物品在容量 w 下的最大价值
dp = [[0] * (W + 1) for _ in range(n + 1)]
for i in range(1, n + 1):
for w in range(1, W + 1):
if weights[i - 1] <= w:
# 选或不选当前物品
dp[i][w] = max(
dp[i - 1][w],
dp[i - 1][w - weights[i - 1]] + values[i - 1]
)
else:
dp[i][w] = dp[i - 1][w]
return dp[n][W]
def knapsack_01_optimized(weights, values, W):
"""空间优化版:一维数组"""
dp = [0] * (W + 1)
for i in range(len(weights)):
for w in range(W, weights[i] - 1, -1):
dp[w] = max(dp[w], dp[w - weights[i]] + values[i])
return dp[W]
if __name__ == "__main__":
weights = [2, 3, 4, 5]
values = [3, 4, 5, 6]
W = 8
result1 = knapsack_01(weights, values, W)
result2 = knapsack_01_optimized(weights, values, W)
print(f"物品重量: {weights}")
print(f"物品价值: {values}")
print(f"背包容量: {W}")
print(f"最大价值 (二维DP): {result1}")
print(f"最大价值 (一维优化): {result2}")
+47
View File
@@ -0,0 +1,47 @@
"""
最长公共子序列 (LCS) — 动态规划
比较两个序列的相似度
"""
def lcs_length(X, Y):
"""计算 LCS 长度并返回 DP 表"""
m, n = len(X), len(Y)
dp = [[0] * (n + 1) for _ in range(m + 1)]
for i in range(1, m + 1):
for j in range(1, n + 1):
if X[i - 1] == Y[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
return dp[m][n], dp
def lcs_backtrack(X, Y, dp):
"""回溯找出 LCS 序列"""
i, j = len(X), len(Y)
result = []
while i > 0 and j > 0:
if X[i - 1] == Y[j - 1]:
result.append(X[i - 1])
i -= 1
j -= 1
elif dp[i - 1][j] > dp[i][j - 1]:
i -= 1
else:
j -= 1
return ''.join(reversed(result))
if __name__ == "__main__":
X = "ABCBDAB"
Y = "BDCABB"
length, dp_table = lcs_length(X, Y)
lcs_str = lcs_backtrack(X, Y, dp_table)
print(f"序列 X: {X}")
print(f"序列 Y: {Y}")
print(f"LCS 长度: {length}")
print(f"LCS 序列: {lcs_str}")
+64
View File
@@ -0,0 +1,64 @@
"""
Huffman 编码 — 贪心算法
构建最优前缀码实现数据压缩
"""
import heapq
from collections import Counter
class HuffmanNode:
def __init__(self, char, freq):
self.char = char
self.freq = freq
self.left = None
self.right = None
def __lt__(self, other):
return self.freq < other.freq
def build_huffman_tree(text):
"""构建 Huffman 树"""
freq = Counter(text)
heap = [HuffmanNode(char, f) for char, f in freq.items()]
heapq.heapify(heap)
while len(heap) > 1:
left = heapq.heappop(heap)
right = heapq.heappop(heap)
merged = HuffmanNode(None, left.freq + right.freq)
merged.left = left
merged.right = right
heapq.heappush(heap, merged)
return heap[0] if heap else None
def generate_codes(node, prefix="", code_map=None):
"""从 Huffman 树生成编码"""
if code_map is None:
code_map = {}
if node is None:
return code_map
if node.char is not None:
code_map[node.char] = prefix or "0"
else:
generate_codes(node.left, prefix + "0", code_map)
generate_codes(node.right, prefix + "1", code_map)
return code_map
if __name__ == "__main__":
text = "ABRACADABRA"
print(f"原文: {text}")
root = build_huffman_tree(text)
codes = generate_codes(root)
print("\nHuffman 编码:")
for char, code in sorted(codes.items()):
print(f" '{char}': {code}")
encoded = "".join(codes[c] for c in text)
print(f"\n编码结果: {encoded}")
print(f"原始大小: {len(text) * 8} bits")
print(f"压缩大小: {len(encoded)} bits")
@@ -0,0 +1,30 @@
"""
活动选择问题 — 贪心算法
选择最多的不重叠活动
"""
def activity_selection(start, finish):
"""贪心选择最早结束的活动"""
n = len(start)
# 按结束时间排序
activities = sorted(zip(start, finish), key=lambda x: x[1])
selected = [activities[0]]
last_finish = activities[0][1]
for i in range(1, n):
if activities[i][0] >= last_finish:
selected.append(activities[i])
last_finish = activities[i][1]
return selected
if __name__ == "__main__":
start = [1, 3, 0, 5, 8, 5]
finish = [2, 4, 6, 7, 9, 9]
result = activity_selection(start, finish)
print("选择的活动 (开始, 结束):")
for s, f in result:
print(f" [{s}, {f})")
print(f"{len(result)} 个活动")
+42
View File
@@ -0,0 +1,42 @@
"""
找零问题 — 贪心算法
使用最少硬币凑出指定金额
"""
def min_coins_greedy(coins, amount):
"""贪心找零(硬币面额需满足贪心选择性质)"""
coins_sorted = sorted(coins, reverse=True)
result = []
remaining = amount
for coin in coins_sorted:
while remaining >= coin:
result.append(coin)
remaining -= coin
return result
def min_coins_dp(coins, amount):
"""动态规划找零(通用解法)"""
MAX = float('inf')
dp = [MAX] * (amount + 1)
dp[0] = 0
for i in range(1, amount + 1):
for coin in coins:
if i >= coin:
dp[i] = min(dp[i], dp[i - coin] + 1)
return dp[amount] if dp[amount] != MAX else -1
if __name__ == "__main__":
coins = [1, 5, 10, 25]
amount = 63
greedy_result = min_coins_greedy(coins, amount)
dp_result = min_coins_dp(coins, amount)
print(f"硬币面额: {coins}")
print(f"需要凑出: {amount}")
print(f"贪心结果: {greedy_result} (共 {len(greedy_result)} 枚)")
print(f"DP最少数量: {dp_result}")