在计算机科学中,贪心算法是一种在每一步选择中都采取当前状态下最好或最优的选择,从而希望导致结果是全局最好或最优的算法策略。相较于动态规划、分治法等算法,贪心算法在解决某些问题时往往更加直观、高效。本文将介绍一些经典编程题,通过贪心算法的巧解,帮助读者提升算法能力。
1. 最小硬币找零问题
问题描述:给定一个整数金额n和一种硬币的面值数组coins,找出需要多少枚硬币来凑出这个金额。
贪心算法思路:选择面值最大的硬币,尽可能多地使用,然后递归地对剩余金额使用同样的方法。
代码示例:
def coinChange(coins, amount):
# 初始化dp数组,dp[i]表示凑出金额i所需的最少硬币数
dp = [float('inf')] * (amount + 1)
dp[0] = 0
for i in range(1, amount + 1):
for coin in coins:
if coin <= i:
dp[i] = min(dp[i], dp[i - coin] + 1)
return dp[amount] if dp[amount] != float('inf') else -1
2. 最长公共子序列
问题描述:给定两个字符串str1和str2,找出它们的公共子序列中长度最长的序列。
贪心算法思路:比较两个字符串的第一个字符,如果相同,则将其加入到公共子序列中,然后分别递归地处理剩余的字符串。
代码示例:
def longestCommonSubsequence(str1, str2):
# 初始化dp数组,dp[i][j]表示str1的前i个字符和str2的前j个字符的公共子序列长度
dp = [[0] * (len(str2) + 1) for _ in range(len(str1) + 1)]
for i in range(1, len(str1) + 1):
for j in range(1, len(str2) + 1):
if str1[i - 1] == str2[j - 1]:
dp[i][j] = dp[i - 1][j - 1] + 1
else:
dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
return dp[len(str1)][len(str2)]
3. 最小路径和
问题描述:给定一个二维数组matrix,其每个元素都是整数,找出从左上角到右下角的最小路径和。
贪心算法思路:从左上角开始,每一步都选择当前行和列的最小值,然后继续这个过程。
代码示例:
def minPathSum(matrix):
rows, cols = len(matrix), len(matrix[0])
for i in range(1, rows):
matrix[i][0] += matrix[i - 1][0]
for j in range(1, cols):
matrix[0][j] += matrix[0][j - 1]
for i in range(1, rows):
for j in range(1, cols):
matrix[i][j] += min(matrix[i - 1][j], matrix[i][j - 1])
return matrix[-1][-1]
通过以上三个经典编程题的贪心算法解法,相信读者已经对贪心算法有了更深入的了解。掌握这些习题,不仅能提升算法能力,还能在面试和实际项目中更加游刃有余。记住,贪心算法的核心在于每一步都做出局部最优的选择,从而期望得到全局最优的结果。
