hello算法,简单讲(1)

文章目录

  • 第一章,简单介绍
  • 递归、迭代以及复杂度分析
    • [1️⃣ 递归与迭代的概念](#1️⃣ 递归与迭代的概念)
    • [2️⃣ 时间复杂度与空间复杂度](#2️⃣ 时间复杂度与空间复杂度)
    • [3️⃣ Python 示例](#3️⃣ Python 示例)
      • [(A) 递归阶乘](#(A) 递归阶乘)
      • [(B) 迭代阶乘](#(B) 迭代阶乘)
    • [4️⃣ 初学者理解小技巧](#4️⃣ 初学者理解小技巧)
    • [5️⃣ 总结](#5️⃣ 总结)
  • 练习题以及答案
    • [**Day 1:算法与数据结构练习**](#Day 1:算法与数据结构练习)
      • [练习题 1️⃣:插入排序(扑克整理)](#练习题 1️⃣:插入排序(扑克整理))
      • [练习题 2️⃣:贪婪找零](#练习题 2️⃣:贪婪找零)
    • [**Day 2:递归与迭代练习**](#Day 2:递归与迭代练习)
      • [练习题 3️⃣:递归阶乘](#练习题 3️⃣:递归阶乘)
      • [练习题 4️⃣:迭代阶乘](#练习题 4️⃣:迭代阶乘)

第一章,简单介绍


1️⃣ 什么是算法?

算法就是一套明确的步骤,用来解决问题,特点:

  • 输入输出明确:明确知道算法处理什么输入,输出什么结果。
  • 步骤可行且有限:每一步操作可以执行,并且算法总会在有限步骤内完成。
  • 相同输入总是得到相同输出:保证结果可预测。

生活中的例子

  1. 查字典(二分搜索算法)

    • 想查拼音首字母为 R 的字
    • 翻到中间,判断字母是前还是后
    • 逐步缩小查找范围,直到找到
      → 数据结构是已排序的数组,算法是二分搜索。
  2. 整理扑克牌(插入排序算法)

    • 把手牌分为有序和无序部分
    • 每次从无序部分抽一张牌,插入到有序部分正确位置
    • 重复,直到牌全部有序
  3. 找零问题(贪婪算法)

    • 买东西找钱,每次选当前能用的最大面额,直到凑够总额
    • 每一步都选"当前最优方案"

2️⃣ 数据结构与算法的关系

  • 数据结构:组织和存储数据的方法(数组、链表、树、哈希表等)
  • 算法:操作这些数据结构的步骤

关系:

  • 数据结构是算法的基础
  • 算法为数据结构赋能
  • 选择合适的数据结构能显著提高效率

类比积木

  • 积木块 → 数据
  • 积木的形状和连接方式 → 数据结构
  • 拼装步骤 → 算法
  • 最终积木模型 → 输出结果

3️⃣ Python 示例

插入排序(整理扑克牌)

python 复制代码
def insertion_sort(arr):
    """
    插入排序算法:将列表从小到大排序
    思路:
    1. 从第二个元素开始,取当前元素 key
    2. 将 key 插入到左边已排序部分的正确位置
    3. 重复直到整个列表有序
    """
    for i in range(1, len(arr)):
        key = arr[i]        # 当前要插入的元素
        j = i - 1
        # 向左扫描已排序部分,如果大于 key,则右移
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]  # 数据右移
            j -= 1
        arr[j + 1] = key    # 插入 key
    return arr

# 测试
cards = [5, 3, 6, 2, 4]
print(insertion_sort(cards))  # 输出:[2, 3, 4, 5, 6]

贪婪找零算法

python 复制代码
def greedy_change(amount, coins):
    """
    贪婪找零算法
    参数:
    - amount: 需要找的总金额
    - coins: 可用的硬币面额列表
    返回:
    - 一个列表,表示找零方案
    思路:
    1. 将硬币从大到小排序
    2. 每次使用当前最大面额的硬币,直到凑够总额
    """
    coins.sort(reverse=True)  # 从大到小排序
    result = []
    for coin in coins:
        while amount >= coin:
            amount -= coin
            result.append(coin)
    return result

# 测试
coins = [20, 10, 5, 1]
amount = 31
print(greedy_change(amount, coins))  # 输出:[20, 10, 1]

4️⃣ 学习建议

  1. 理解概念:先理解算法逻辑,再看代码实现。
  2. 动手实践:敲代码、调试输出,观察算法如何改变数据。
  3. 联系生活:把查字典、整理扑克牌、找零问题想成生活小任务。

递归、迭代以及复杂度分析


1️⃣ 递归与迭代的概念

迭代(Iteration)

迭代是通过重复执行一段代码来完成任务,通常用 forwhile 循环实现。每一步都是显式的"循环操作",非常直观。

递归(Recursion)

递归是函数自己调用自己来完成任务。递归通常有两个部分:

  1. 终止条件(Base case):当问题规模最小或满足条件时,不再递归。
  2. 递归步骤(Recursive step):将问题拆解为更小的子问题,并通过函数自身求解。

💡 核心区别:迭代用循环显式推进,递归通过函数调用隐式推进。


2️⃣ 时间复杂度与空间复杂度

  • 时间复杂度:算法执行所需时间的增长量。比如阶乘函数对 n 的计算量:

    • 迭代:O(n)
    • 递归:O(n)
  • 空间复杂度:算法执行所需额外空间:

    • 迭代:O(1)(常量空间)
    • 递归:O(n)(递归调用会占用栈空间)

所以递归虽然逻辑简洁,但可能占用更多内存,需要注意"栈溢出"问题。


3️⃣ Python 示例

(A) 递归阶乘

python 复制代码
def factorial_recursive(n):
    """
    递归实现阶乘
    阶乘 n! = n * (n-1)!, 0! = 1
    """
    if n == 0 or n == 1:  # 终止条件
        return 1
    return n * factorial_recursive(n - 1)  # 递归调用

# 测试
print(factorial_recursive(5))  # 输出: 120

(B) 迭代阶乘

python 复制代码
def factorial_iterative(n):
    """
    迭代实现阶乘
    通过循环累乘
    """
    result = 1
    for i in range(2, n + 1):
        result *= i  # 累乘
    return result

# 测试
print(factorial_iterative(5))  # 输出: 120

4️⃣ 初学者理解小技巧

  1. 手动演算

    • factorial_recursive(4),手动画出函数调用栈:

      复制代码
      factorial_recursive(4)
        -> 4 * factorial_recursive(3)
             -> 3 * factorial_recursive(2)
                  -> 2 * factorial_recursive(1)
                       -> 1

      然后从栈底向上计算:1 → 2 → 6 → 24

  2. 对比迭代

    • 用循环累乘:2 → 6 → 24,过程更直观,但没有"函数栈"的概念。
  3. 复杂度分析

    • 两者时间复杂度相同 O(n)
    • 递归额外消耗栈空间 O(n),迭代只需要一个变量 O(1)

5️⃣ 总结

  • 递归适合逻辑清晰、可分解为相似子问题的场景(如树遍历、分治问题)。
  • 迭代适合对空间敏感或者操作简单的线性任务。
  • 复杂度分析帮助你理解算法在大规模输入下的性能表现,是算法设计的基础。

练习题以及答案


Day 1:算法与数据结构练习

练习题 1️⃣:插入排序(扑克整理)

题目 :给定列表 [7, 2, 5, 3, 4],用插入排序将它从小到大排序,并画出每一步元素移动的变化过程。

参考代码

python 复制代码
def insertion_sort(arr):
    for i in range(1, len(arr)):
        key = arr[i]
        j = i - 1
        while j >= 0 and arr[j] > key:
            arr[j + 1] = arr[j]  # 元素右移
            j -= 1
        arr[j + 1] = key
    return arr

cards = [7, 2, 5, 3, 4]
print(insertion_sort(cards))  # 输出: [2, 3, 4, 5, 7]

讲解

  1. 从第二个元素 2 开始,向左扫描 [7],发现 7>2,右移 7,插入 2[2,7,5,3,4]
  2. 5,扫描 [2,7],右移 7,插入 5[2,5,7,3,4]
  3. 3,扫描 [2,5,7],右移 7,5,插入 3[2,3,5,7,4]
  4. 4,扫描 [2,3,5,7],右移 7,5,插入 4[2,3,4,5,7]

每一步都是把"未排序的元素"插入到"已排序部分"的正确位置。


练习题 2️⃣:贪婪找零

题目 :超市买东西找零,硬币面额 [10,5,2,1],总金额 18,每次选择最大可用面额的硬币,计算找零方案。

参考代码

python 复制代码
def greedy_change(amount, coins):
    coins.sort(reverse=True)
    result = []
    for coin in coins:
        while amount >= coin:
            amount -= coin
            result.append(coin)
    return result

coins = [10, 5, 2, 1]
amount = 18
print(greedy_change(amount, coins))  # 输出: [10,5,2,1]

讲解

  • 贪婪策略:每一步都选择当前能用的最大面额。

  • 步骤:

    1. 10 → 剩余 8
    2. 5 → 剩余 3
    3. 2 → 剩余 1
    4. 1 → 剩余 0
  • 优点:逻辑简单,效率高。缺点:在某些面额组合下可能不是最优(此例最优)。


Day 2:递归与迭代练习

练习题 3️⃣:递归阶乘

题目 :实现函数 factorial_recursive(n),用递归计算阶乘 n!,测试 n=5

参考代码

python 复制代码
def factorial_recursive(n):
    if n == 0 or n == 1:  # 终止条件
        return 1
    return n * factorial_recursive(n - 1)

print(factorial_recursive(5))  # 输出: 120

讲解

  • 核心思路:n! = n * (n-1)!

  • 调用栈展开过程:

    复制代码
    factorial_recursive(5)
      -> 5 * factorial_recursive(4)
          -> 4 * factorial_recursive(3)
              -> 3 * factorial_recursive(2)
                  -> 2 * factorial_recursive(1)
                      -> 1
  • 从栈底开始返回计算结果:1 → 2 → 6 → 24 → 120


练习题 4️⃣:迭代阶乘

题目 :实现函数 factorial_iterative(n),用循环计算阶乘,测试 n=5

参考代码

python 复制代码
def factorial_iterative(n):
    result = 1
    for i in range(2, n+1):
        result *= i
    return result

print(factorial_iterative(5))  # 输出: 120

讲解

  • 通过循环依次累乘 2*3*4*5,直观且节省递归栈空间。
  • 时间复杂度与递归相同 O(n),但空间复杂度更低 O(1)。

💡 学习提示

  • 对插入排序和贪婪找零,可以画出每一步元素移动或找零选择过程,更直观理解算法逻辑。
  • 对递归阶乘,建议手动画调用栈,理解"从终止条件返回结果"的顺序。
  • 可尝试对比迭代与递归,观察时间和空间消耗差异,加深复杂度分析理解。
相关推荐
y = xⁿ1 小时前
20天速通LeetCodeday15:BFS广度优先搜索
算法·宽度优先
目黑live +wacyltd1 小时前
算法备案:常见驳回原因与应对策略
人工智能·算法
磊 子2 小时前
多态类原理+四种类型转换+异常处理
开发语言·c++·算法
染指11103 小时前
3.AI大模型-token是什么-大模型底层运行机制
人工智能·算法·机器学习
谙弆悕博士3 小时前
快速学C语言——第19章:C语言常用开发库
c语言·开发语言·算法·业界资讯·常用函数
光影少年3 小时前
前端算法题
前端·javascript·算法
南宫萧幕3 小时前
基于 Simulink 与 Python 联合仿真的 eVTOL 强化学习全链路实战
开发语言·人工智能·python·算法·机器学习·控制
电魂泡哥3 小时前
CMS垃圾回收
java·jvm·算法