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

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


一、核心概念

  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. 需要证明正确性
    • 使用贪心算法时,必须证明其局部最优解能导致全局最优解。

五、适用问题特征

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

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

相关推荐
双叶8362 小时前
(C语言)写一个递归函数DigitSum(n),输入一个非负整数,返回组成它的数字之和(递归函数)
c语言·开发语言·数据结构·算法·游戏
BineHello2 小时前
强化学习 - PPO控制无人机
人工智能·算法·自动驾驶·动态规划·无人机·强化学习
阿饼2402 小时前
算法——层序遍历和中序遍历构造二叉树
数据结构·算法
贫道绝缘子3 小时前
Leetcode-132.Palindrome Partitioning II [C++][Java]
java·c++·算法·leetcode
spatial_coder4 小时前
deepseek GRPO算法保姆级讲解(数学原理+源码解析+案例实战)
人工智能·算法
earthzhang20214 小时前
《Python深度学习》第四讲:计算机视觉中的深度学习
人工智能·python·深度学习·算法·计算机视觉·numpy·1024程序员节
小咖拉眯5 小时前
蓝桥杯进制问题秒破解法|冲击省一题单(二)
java·数据结构·算法·蓝桥杯
一只_程序媛5 小时前
【leetcode hot 100 146】LRU缓存
算法·leetcode·缓存
kkk16222456 小时前
C# Winform 实现换肤,并自定义皮肤功能
java·算法·c#