算法ALGO

7 minute read

算法 系统学习大纲(以python示例)

葵花宝典:hello算法
力扣刷题:力扣LeetCode

一、算法基础

  • 1.1 算法定义与特性
    • 什么是算法
    • 算法的五个特性:有穷性、确定性、可行性、输入、输出
    • 算法与程序的区别
  • 1.2 算法复杂度分析
    • 时间复杂度
    • 空间复杂度
    • 大O表示法
    • 最好、最坏、平均情况复杂度
    • 时间复杂度比较
  • 1.3 算法效率评估方法
    • 理论分析
    • 实验测量
    • 渐近分析
  • 1.4 算法描述方法
    • 自然语言
    • 流程图
    • 伪代码
    • 编程语言实现

二、基础数据结构

  • 2.1 数组
    • 数组基本操作
    • 多维数组
    • 动态数组
    # 数组基本操作
    arr = [1, 2, 3, 4, 5]
    
    # 访问元素
    print(arr[0])  # 输出: 1
    
    # 插入元素
    arr.insert(2, 10)  # 在索引2插入10
    
    # 删除元素
    arr.pop(3)  # 删除索引3的元素
    
    # 遍历数组
    for i in range(len(arr)):
        print(arr[i])
    
  • 2.2 链表
    • 单向链表
    • 双向链表
    • 循环链表
    • 链表基本操作
    # 单链表节点定义
    class ListNode:
        def __init__(self, val=0, next=None):
            self.val = val
            self.next = next
    
    # 链表遍历
    def traverse_list(head):
        current = head
        while current:
            print(current.val)
            current = current.next
    
  • 2.3 栈
    • 栈的定义与特性
    • 栈的实现
    • 栈的应用
    # 栈的实现
    class Stack:
        def __init__(self):
            self.items = []
            
        def push(self, item):
            self.items.append(item)
            
        def pop(self):
            if not self.is_empty():
                return self.items.pop()
            
        def peek(self):
            if not self.is_empty():
                return self.items[-1]
            
        def is_empty(self):
            return len(self.items) == 0
            
        def size(self):
            return len(self.items)
    
  • 2.4 队列
    • 队列的定义与特性
    • 普通队列
    • 双端队列
    • 优先队列
    • 循环队列
    # 队列实现
    class Queue:
        def __init__(self):
            self.items = []
            
        def enqueue(self, item):
            self.items.insert(0, item)
            
        def dequeue(self):
            if not self.is_empty():
                return self.items.pop()
            
        def is_empty(self):
            return len(self.items) == 0
            
        def size(self):
            return len(self.items)
    
  • 2.5 哈希表
    • 哈希函数
    • 冲突解决
    • 装载因子
    • 哈希表实现
    # 哈希表简单实现
    class HashTable:
        def __init__(self, size=10):
            self.size = size
            self.table = [[] for _ in range(size)]
            
        def _hash(self, key):
            return hash(key) % self.size
            
        def put(self, key, value):
            hash_key = self._hash(key)
            for i, (k, v) in enumerate(self.table[hash_key]):
                if k == key:
                    self.table[hash_key][i] = (key, value)
                    return
            self.table[hash_key].append((key, value))
            
        def get(self, key):
            hash_key = self._hash(key)
            for k, v in self.table[hash_key]:
                if k == key:
                    return v
            return None
    

三、排序算法

  • 3.1 排序算法分类
    • 比较排序 vs 非比较排序
    • 内部排序 vs 外部排序
    • 稳定排序 vs 不稳定排序
  • 3.2 简单排序
    • 冒泡排序
    • 选择排序
    • 插入排序
    # 冒泡排序
    def bubble_sort(arr):
        n = len(arr)
        for i in range(n-1):
            for j in range(n-i-1):
                if arr[j] > arr[j+1]:
                    arr[j], arr[j+1] = arr[j+1], arr[j]
        return arr
    
  • 3.3 高级排序
    • 快速排序
    • 归并排序
    • 堆排序
    • 希尔排序
    # 快速排序
    def quick_sort(arr):
        if len(arr) <= 1:
            return arr
        pivot = arr[len(arr)//2]
        left = [x for x in arr if x < pivot]
        middle = [x for x in arr if x == pivot]
        right = [x for x in arr if x > pivot]
        return quick_sort(left) + middle + quick_sort(right)
    
  • 3.4 线性排序
    • 计数排序
    • 桶排序
    • 基数排序
  • 3.5 排序算法比较
    • 时间复杂度对比
    • 空间复杂度对比
    • 稳定性对比
    • 适用场景

四、搜索算法

  • 4.1 线性搜索
    • 顺序查找
    • 哨兵查找
    # 线性搜索
    def linear_search(arr, target):
        for i in range(len(arr)):
            if arr[i] == target:
                return i
        return -1
    
  • 4.2 二分搜索
    • 二分查找原理
    • 二分查找实现
    • 二分查找变体
    # 二分搜索
    def binary_search(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:
                left = mid + 1
            else:
                right = mid - 1
        return -1
    
  • 4.3 哈希搜索
    • 哈希查找
    • 布隆过滤器
  • 4.4 树形搜索
    • 二叉搜索树
    • B树/B+树
  • 4.5 字符串搜索
    • KMP算法
    • Boyer-Moore算法
    • Rabin-Karp算法
    # KMP算法
    def kmp_search(text, pattern):
        def build_lps(pattern):
            lps = [0] * len(pattern)
            length = 0
            i = 1
            while i < len(pattern):
                if pattern[i] == pattern[length]:
                    length += 1
                    lps[i] = length
                    i += 1
                else:
                    if length != 0:
                        length = lps[length-1]
                    else:
                        lps[i] = 0
                        i += 1
            return lps
            
        lps = build_lps(pattern)
        i = j = 0
        while i < len(text):
            if pattern[j] == text[i]:
                i += 1
                j += 1
            if j == len(pattern):
                return i - j
            elif i < len(text) and pattern[j] != text[i]:
                if j != 0:
                    j = lps[j-1]
                else:
                    i += 1
        return -1
    

五、递归与分治

  • 5.1 递归基础
    • 递归定义
    • 递归三要素
    • 递归调用栈
  • 5.2 递归算法设计
    • 递归式求解
    • 递归树
    • 主定理
  • 5.3 分治算法
    • 分治策略
    • 分治算法设计
    • 分治算法分析
    # 归并排序(分治算法)
    def merge_sort(arr):
        if len(arr) <= 1:
            return arr
            
        mid = len(arr) // 2
        left = merge_sort(arr[:mid])
        right = merge_sort(arr[mid:])
            
        return merge(left, right)
    
    def merge(left, right):
        result = []
        i = j = 0
            
        while i < len(left) and j < len(right):
            if left[i] < right[j]:
                result.append(left[i])
                i += 1
            else:
                result.append(right[j])
                j += 1
            
        result.extend(left[i:])
        result.extend(right[j:])
        return result
    
  • 5.4 递归与迭代转换
    • 尾递归优化
    • 递归转迭代
  • 5.5 分治算法应用
    • 大整数乘法
    • 快速傅里叶变换
    • 最近点对问题

六、动态规划

  • 6.1 动态规划基础
    • 最优子结构
    • 重叠子问题
    • 状态转移方程
  • 6.2 动态规划步骤
    • 定义状态
    • 确定状态转移
    • 确定初始条件
    • 计算顺序
  • 6.3 经典动态规划问题
    • 斐波那契数列
    • 最长公共子序列
    • 最长递增子序列
    • 0-1背包问题
    • 完全背包问题
    # 斐波那契数列(动态规划)
    def fibonacci_dp(n):
        if n <= 1:
            return n
            
        dp = [0] * (n + 1)
        dp[1] = 1
            
        for i in range(2, n + 1):
            dp[i] = dp[i-1] + dp[i-2]
            
        return dp[n]
    
    # 0-1背包问题
    def knapsack_01(weights, values, capacity):
        n = len(weights)
        dp = [[0] * (capacity + 1) for _ in range(n + 1)]
            
        for i in range(1, n + 1):
            for w in range(1, capacity + 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][capacity]
    
  • 6.4 动态规划优化
    • 空间优化
    • 状态压缩
    • 记忆化搜索
  • 6.5 动态规划应用
    • 编辑距离
    • 矩阵链乘法
    • 最优二叉搜索树
    • 旅行商问题

七、贪心算法

  • 7.1 贪心算法基础
    • 贪心选择性质
    • 最优子结构
    • 贪心算法与动态规划区别
  • 7.2 贪心算法设计
    • 贪心策略选择
    • 算法正确性证明
  • 7.3 经典贪心算法问题
    • 活动选择问题
    • 霍夫曼编码
    • 最小生成树
    • 单源最短路径
    # 活动选择问题
    def activity_selection(start, finish):
        n = len(start)
        activities = []
            
        # 按结束时间排序
        sorted_activities = sorted(zip(finish, start))
        finish_sorted, start_sorted = zip(*sorted_activities)
            
        i = 0
        activities.append(0)
            
        for j in range(1, n):
            if start_sorted[j] >= finish_sorted[i]:
                activities.append(j)
                i = j
            
        return activities
    
  • 7.4 贪心算法应用
    • 找零钱问题
    • 区间调度问题
    • 任务调度问题
    • 集合覆盖问题

八、回溯算法

  • 8.1 回溯算法基础
    • 回溯法定义
    • 解空间树
    • 剪枝函数
  • 8.2 回溯算法框架
    • 递归回溯
    • 迭代回溯
  • 8.3 经典回溯问题
    • N皇后问题
    • 子集和问题
    • 全排列
    • 组合问题
    # N皇后问题
    def solve_n_queens(n):
        def is_safe(board, row, col):
            # 检查列
            for i in range(row):
                if board[i][col] == 'Q':
                    return False
                
            # 检查左上对角线
            i, j = row-1, col-1
            while i >= 0 and j >= 0:
                if board[i][j] == 'Q':
                    return False
                i -= 1
                j -= 1
                
            # 检查右上对角线
            i, j = row-1, col+1
            while i >= 0 and j < n:
                if board[i][j] == 'Q':
                    return False
                i -= 1
                j += 1
                
            return True
            
        def backtrack(row):
            if row == n:
                result.append([''.join(row) for row in board])
                return
                
            for col in range(n):
                if is_safe(board, row, col):
                    board[row][col] = 'Q'
                    backtrack(row+1)
                    board[row][col] = '.'
            
        result = []
        board = [['.' for _ in range(n)] for _ in range(n)]
        backtrack(0)
        return result
    
  • 8.4 回溯算法优化
    • 可行性剪枝
    • 最优性剪枝
    • 记忆化
  • 8.5 回溯算法应用
    • 数独求解
    • 图的着色问题
    • 哈密顿回路
    • 0-1背包问题

九、图算法

  • 9.1 图的基本概念
    • 图的定义
    • 图的表示
    • 图的基本术语
    # 图的邻接表表示
    class Graph:
        def __init__(self, vertices):
            self.vertices = vertices
            self.adj_list = {v: [] for v in range(vertices)}
            
        def add_edge(self, u, v):
            self.adj_list[u].append(v)
            self.adj_list[v].append(u)  # 无向图
    
  • 9.2 图的遍历
    • 深度优先搜索
    • 广度优先搜索
    # 深度优先搜索
    def dfs(graph, start, visited=None):
        if visited is None:
            visited = set()
        visited.add(start)
        print(start, end=' ')
            
        for neighbor in graph.adj_list[start]:
            if neighbor not in visited:
                dfs(graph, neighbor, visited)
            
        return visited
    
  • 9.3 最短路径算法
    • Dijkstra算法
    • Bellman-Ford算法
    • Floyd-Warshall算法
  • 9.4 最小生成树
    • Kruskal算法
    • Prim算法
  • 9.5 拓扑排序
    • 拓扑排序算法
    • 应用场景
  • 9.6 强连通分量
    • Kosaraju算法
    • Tarjan算法
  • 9.7 网络流算法
    • 最大流
    • 最小割
    • Ford-Fulkerson算法
    • Edmonds-Karp算法

十、高级数据结构

  • 10.1 树
    • 二叉树
    • 二叉搜索树
    • 平衡二叉树
    • B树/B+树
    • 线段树
    • 树状数组
    # 二叉搜索树
    class TreeNode:
        def __init__(self, val=0, left=None, right=None):
            self.val = val
            self.left = left
            self.right = right
    
    class BST:
        def __init__(self):
            self.root = None
            
        def insert(self, val):
            if not self.root:
                self.root = TreeNode(val)
            else:
                self._insert(self.root, val)
            
        def _insert(self, node, val):
            if val < node.val:
                if not node.left:
                    node.left = TreeNode(val)
                else:
                    self._insert(node.left, val)
            else:
                if not node.right:
                    node.right = TreeNode(val)
                else:
                    self._insert(node.right, val)
    
  • 10.2 堆
    • 二叉堆
    • 优先队列
    • 左偏树
  • 10.3 并查集
    • 并查集操作
    • 路径压缩
    • 按秩合并
    # 并查集
    class UnionFind:
        def __init__(self, n):
            self.parent = list(range(n))
            self.rank = [0] * n
            
        def find(self, x):
            if self.parent[x] != x:
                self.parent[x] = self.find(self.parent[x])
            return self.parent[x]
            
        def union(self, x, y):
            root_x = self.find(x)
            root_y = self.find(y)
                
            if root_x != root_y:
                if self.rank[root_x] < self.rank[root_y]:
                    self.parent[root_x] = root_y
                elif self.rank[root_x] > self.rank[root_y]:
                    self.parent[root_y] = root_x
                else:
                    self.parent[root_y] = root_x
                    self.rank[root_x] += 1
                return True
            return False
    
  • 10.4 Trie树
    • Trie树实现
    • 应用场景
  • 10.5 跳表
    • 跳表原理
    • 跳表操作
  • 10.6 布隆过滤器
    • 布隆过滤器原理
    • 应用场景

十一、字符串算法

  • 11.1 字符串匹配
    • 朴素算法
    • KMP算法
    • Rabin-Karp算法
  • 11.2 字符串处理
    • 字符串反转
    • 字符串分割
    • 字符串替换
  • 11.3 正则表达式
    • 正则语法
    • 正则引擎
  • 11.4 字典树
    • Trie树
    • 后缀树
    • 后缀数组
  • 11.5 字符串压缩
    • 哈夫曼编码
    • LZW算法

十二、数论算法

  • 12.1 基本数论
    • 质数判定
    • 最大公约数
    • 最小公倍数
  • 12.2 模运算
    • 模运算性质
    • 模逆元
    • 中国剩余定理
  • 12.3 素数算法
    • 埃拉托斯特尼筛法
    • 欧拉筛法
    • 米勒-拉宾素性测试
    # 埃拉托斯特尼筛法
    def sieve_of_eratosthenes(n):
        is_prime = [True] * (n+1)
        is_prime[0] = is_prime[1] = False
            
        for i in range(2, int(n**0.5)+1):
            if is_prime[i]:
                for j in range(i*i, n+1, i):
                    is_prime[j] = False
            
        primes = [i for i in range(2, n+1) if is_prime[i]]
        return primes
    
  • 12.4 快速幂
    • 快速幂算法
    • 矩阵快速幂
  • 12.5 组合数学
    • 排列组合
    • 二项式系数
    • 卡特兰数

十三、计算几何

  • 13.1 基本几何对象
    • 向量
    • 直线
    • 多边形
  • 13.2 几何运算
    • 点积
    • 叉积
    • 距离计算
  • 13.3 几何算法
    • 凸包算法
    • 线段相交判断
    • 多边形包含判断
  • 13.4 扫描线算法
    • 扫描线原理
    • 应用场景

十四、近似算法

  • 14.1 近似算法基础
    • 近似比
    • 近似方案
  • 14.2 经典近似问题
    • 旅行商问题
    • 顶点覆盖
    • 集合覆盖
  • 14.3 随机化算法
    • 随机化快速排序
    • 随机化选择算法
  • 14.4 启发式算法
    • 遗传算法
    • 模拟退火
    • 蚁群算法

十五、算法设计范式

  • 15.1 穷举法
    • 朴素穷举
    • 分支限界
  • 15.2 递推法
    • 递推关系
    • 递推求解
  • 15.3 迭代法
    • 迭代改进
    • 不动点迭代
  • 15.4 随机化方法
    • 蒙特卡洛方法
    • 拉斯维加斯方法
  • 15.5 并行算法
    • 并行计算模型
    • 并行算法设计

十六、算法优化

  • 16.1 时间优化
    • 减少循环
    • 提前终止
    • 记忆化
  • 16.2 空间优化
    • 原地操作
    • 滚动数组
    • 压缩存储
  • 16.3 代码优化
    • 避免重复计算
    • 使用内置函数
    • 选择合适数据结构
  • 16.4 算法选择策略
    • 问题特征分析
    • 算法适用性评估
    • 性能权衡

十七、算法竞赛

  • 17.1 竞赛平台
    • LeetCode
    • Codeforces
    • AtCoder
    • HackerRank
  • 17.2 竞赛技巧
    • 问题分析
    • 解题策略
    • 调试技巧
  • 17.3 常用模板
    • 输入输出模板
    • 常用算法模板
    • 数据结构模板
  • 17.4 比赛策略
    • 时间管理
    • 题目选择
    • 团队协作

十八、学习资源

  • 18.1 经典书籍
    • 《算法导论》
    • 《算法》
    • 《编程珠玑》
  • 18.2 在线课程
    • 中国大学MOOC
    • Coursera
    • 极客时间
  • 18.3 刷题平台
    • LeetCode
    • 牛客网
    • 洛谷
  • 18.4 实践项目
    • 实现经典算法
    • 参与开源项目
    • 算法可视化
  • 18.5 社区资源
    • 算法论坛
    • 技术博客
    • GitHub仓库