五大基础算法——贪心算法

贪心算法 是一种在每一步选择中都采取当前最优决策,希望通过局部最优解达到全局最优解的算法思想。它简单高效,但并非所有问题都适用。以下是贪心算法的核心概念、适用条件、经典问题及实现方法:


一、核心概念

  1. 局部最优解
    • 在每一步选择中,贪心算法只考虑当前状态下的最优解,而不考虑后续步骤的影响。
  2. 无后效性
    • 当前的选择不会影响后续选择的状态。
  3. 全局最优解
    • 通过一系列局部最优解,最终希望得到全局最优解。

二、适用条件

贪心算法适用于满足以下条件的问题:

  1. 贪心选择性质
    • 问题的全局最优解可以通过一系列局部最优解得到。
  2. 最优子结构
    • 问题的最优解包含其子问题的最优解。
  3. 无后效性
    • 当前的选择不会影响后续选择的状态。

三、经典问题与代码

1. 零钱兑换(硬币问题)

问题描述:给定不同面额的硬币和一个总金额,求最少需要多少枚硬币才能凑成总金额。

python 复制代码
def coinChange(coins, amount):
    coins.sort(reverse=True)  # 从大到小排序
    count = 0
    for coin in coins:
        if amount == 0:
            break
        count += amount // coin
        amount %= coin
    return count if amount == 0 else -1

# 示例
coins = [1, 2, 5]
amount = 11
print(coinChange(coins, amount))  # 输出 3 (5+5+1)
2. 活动选择问题

问题描述:给定一组活动,每个活动有开始时间和结束时间,求最多能安排多少个互不冲突的活动。

python 复制代码
def activitySelection(activities):
    activities.sort(key=lambda x: x[1])  # 按结束时间排序
    selected = []
    last_end = -1
    for start, end in activities:
        if start >= last_end:
            selected.append((start, end))
            last_end = end
    return selected

# 示例
activities = [(1, 4), (3, 5), (0, 6), (5, 7), (8, 9)]
print(activitySelection(activities))  # 输出 [(1, 4), (5, 7), (8, 9)]
3. 最小生成树(Kruskal算法)

问题描述:给定一个带权无向图,求其最小生成树。

python 复制代码
def kruskal(graph):
    edges = sorted(graph['edges'], key=lambda x: x[2])  # 按权重排序
    parent = {node: node for node in graph['nodes']}
    result = []
    
    def find(u):
        while parent[u] != u:
            parent[u] = parent[parent[u]]  # 路径压缩
            u = parent[u]
        return u
    
    for u, v, w in edges:
        if find(u) != find(v):
            result.append((u, v, w))
            parent[find(u)] = find(v)
    return result

# 示例
graph = {
    'nodes': ['A', 'B', 'C', 'D'],
    'edges': [('A', 'B', 1), ('B', 'C', 2), ('C', 'D', 3), ('A', 'D', 4)]
}
print(kruskal(graph))  # 输出 [('A', 'B', 1), ('B', 'C', 2), ('C', 'D', 3)]

四、贪心算法的局限性

  1. 不保证全局最优
    • 贪心算法只能保证局部最优,不一定能得到全局最优解。
  2. 适用问题有限
    • 只有满足贪心选择性质和最优子结构的问题才能使用贪心算法。
  3. 需要证明正确性
    • 使用贪心算法时,必须证明其局部最优解能导致全局最优解。

五、适用问题特征

  • 问题可以分解为一系列子问题。
  • 子问题的最优解能组合成全局最优解。
  • 常见问题包括:区间调度、最小生成树、最短路径、零钱兑换等。

贪心算法是一种高效的算法思想,但需要仔细分析问题是否满足其适用条件。在实际应用中,通常需要结合其他算法(如动态规划)来解决更复杂的问题。

相关推荐
罗西的思考1 天前
机器人 / 强化学习】HIL-SERL:人类在环驱动的具身智能进化框架
人工智能·算法·机器学习
美团技术团队2 天前
LongCat 开源 VitaBench 2.0:长期动态智能体基准新标杆
人工智能·算法
To_OC2 天前
LC 207 课程表:刚学图论那会儿,我连这是拓扑排序都没看出来
javascript·算法·leetcode
To_OC2 天前
LC 208 实现 Trie 前缀树:曾被名字劝退,写完发现是送分题
javascript·算法·leetcode
BadBadBad__AK2 天前
线段树维护区间 k 次方和
c++·数学·算法·stl
_清歌3 天前
DSpark 深度解读:DeepSeek-V4 如何用「半自回归」把推理速度提升 85%
算法
统计实现局3 天前
SVD 的三步走:双对角化、Givens 收敛、排序
算法
躬行见万象3 天前
《VLA 系列》UniLab 强化训练 | G1 机器人 |复现
算法
统计实现局3 天前
对称不定分解(Bunch-Kaufman):为什么 Cholesky 不够用
算法