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

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


一、核心概念

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

五、适用问题特征

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

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

相关推荐
浅念-5 小时前
递归解题指南:LeetCode经典题全解析
数据结构·算法·leetcode·职场和发展·排序算法·深度优先·递归
Kiling_07045 小时前
Java集合进阶:Set与Collections详解
算法·哈希算法
智者知已应修善业6 小时前
【51单片机89C51及74LS273、74LS244组成】2022-5-28
c++·经验分享·笔记·算法·51单片机
洛水水6 小时前
【力扣100题】33.验证二叉搜索树
算法·leetcode·职场和发展
SimpleLearingAI6 小时前
聚类算法详解
算法·数据挖掘·聚类
刀法如飞7 小时前
Go 字符串查找的 20 种实现方式,用不同思路解决问题
算法·面试·程序员
Dlrb12119 小时前
C语言-指针数组与数组指针
c语言·数据结构·算法·指针·数组指针·指针数组·二级指针
WL_Aurora9 小时前
Python 算法基础篇之集合
python·算法
平行侠9 小时前
A15 工业路由器IP前缀高速检索与内存压缩系统
网络·tcp/ip·算法
阿旭超级学得完10 小时前
C++11包装器(function和bind)
java·开发语言·c++·算法·哈希算法·散列表